[glib-networking/wip/openssl] Try to handle bio in a thread safe way
- From: Ignacio Casal Quinteiro <icq src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking/wip/openssl] Try to handle bio in a thread safe way
- Date: Wed, 20 Jan 2016 12:41:02 +0000 (UTC)
commit 38cfda55d2fd7a73caa113a7233652e6220eeedd
Author: Ignacio Casal Quinteiro <icq gnome org>
Date: Wed Jan 20 13:40:22 2016 +0100
Try to handle bio in a thread safe way
We might want to handle more errors!
tls/openssl/gtlsbio.c | 74 +++++++++++++++++----------------
tls/openssl/gtlsbio.h | 6 ---
tls/openssl/gtlsconnection-openssl.c | 54 +++++++++++++++++-------
3 files changed, 76 insertions(+), 58 deletions(-)
---
diff --git a/tls/openssl/gtlsbio.c b/tls/openssl/gtlsbio.c
index dad0d75..e998673 100644
--- a/tls/openssl/gtlsbio.c
+++ b/tls/openssl/gtlsbio.c
@@ -32,8 +32,8 @@ typedef struct {
GCancellable *write_cancellable;
gboolean read_blocking;
gboolean write_blocking;
- GError **read_error;
- GError **write_error;
+ GMutex read_mutex;
+ GMutex write_mutex;
} GTlsBio;
static void
@@ -113,17 +113,29 @@ gtls_bio_write (BIO *bio,
int inl)
{
GTlsBio *gbio;
+ gssize ret;
+ GError *error = NULL;
if (!bio->init || in == NULL || inl == 0)
return 0;
gbio = (GTlsBio *)bio->ptr;
- return g_pollable_stream_write (g_io_stream_get_output_stream (gbio->io_stream),
- in, inl,
- gbio->write_blocking,
- gbio->write_cancellable,
- gbio->write_error);
+ g_mutex_lock (&gbio->write_mutex);
+ ret = g_pollable_stream_write (g_io_stream_get_output_stream (gbio->io_stream),
+ in, inl,
+ gbio->write_blocking,
+ gbio->write_cancellable,
+ &error);
+ g_mutex_unlock (&gbio->write_mutex);
+
+ if (ret == -1)
+ {
+ ret = -error->code;
+ g_error_free (error);
+ }
+
+ return ret;
}
static int
@@ -132,17 +144,29 @@ gtls_bio_read (BIO *bio,
int outl)
{
GTlsBio *gbio;
+ gssize ret;
+ GError *error = NULL;
if (!bio->init || out == NULL || outl == 0)
return 0;
gbio = (GTlsBio *)bio->ptr;
- return g_pollable_stream_read (g_io_stream_get_input_stream (gbio->io_stream),
- out, outl,
- gbio->read_blocking,
- gbio->read_cancellable,
- gbio->read_error);
+ g_mutex_lock (&gbio->read_mutex);
+ ret = g_pollable_stream_read (g_io_stream_get_input_stream (gbio->io_stream),
+ out, outl,
+ gbio->read_blocking,
+ gbio->read_cancellable,
+ &error);
+ g_mutex_unlock (&gbio->read_mutex);
+
+ if (ret == -1)
+ {
+ ret = -error->code;
+ g_error_free (error);
+ }
+
+ return ret;
}
static int
@@ -190,6 +214,8 @@ g_tls_bio_new (GIOStream *io_stream)
gbio = g_new0 (GTlsBio, 1);
gbio->io_stream = g_object_ref (io_stream);
+ g_mutex_init (&gbio->read_mutex);
+ g_mutex_init (&gbio->write_mutex);
ret->ptr = gbio;
ret->init = 1;
@@ -222,18 +248,6 @@ g_tls_bio_set_read_blocking (BIO *bio,
}
void
-g_tls_bio_set_read_error (BIO *bio,
- GError **error)
-{
- GTlsBio *gbio;
-
- g_return_if_fail (bio != NULL);
-
- gbio = (GTlsBio *)bio->ptr;
- gbio->read_error = error;
-}
-
-void
g_tls_bio_set_write_cancellable (BIO *bio,
GCancellable *cancellable)
{
@@ -256,15 +270,3 @@ g_tls_bio_set_write_blocking (BIO *bio,
gbio = (GTlsBio *)bio->ptr;
gbio->write_blocking = blocking;
}
-
-void
-g_tls_bio_set_write_error (BIO *bio,
- GError **error)
-{
- GTlsBio *gbio;
-
- g_return_if_fail (bio != NULL);
-
- gbio = (GTlsBio *)bio->ptr;
- gbio->write_error = error;
-}
diff --git a/tls/openssl/gtlsbio.h b/tls/openssl/gtlsbio.h
index 701f5d1..1247dd7 100644
--- a/tls/openssl/gtlsbio.h
+++ b/tls/openssl/gtlsbio.h
@@ -38,18 +38,12 @@ void g_tls_bio_set_read_cancellable (BIO *bio,
void g_tls_bio_set_read_blocking (BIO *bio,
gboolean blocking);
-void g_tls_bio_set_read_error (BIO *bio,
- GError **error);
-
void g_tls_bio_set_write_cancellable (BIO *bio,
GCancellable *cancellable);
void g_tls_bio_set_write_blocking (BIO *bio,
gboolean blocking);
-void g_tls_bio_set_write_error (BIO *bio,
- GError **error);
-
G_END_DECLS
#endif /* __G_TLS_BIO_H__ */
diff --git a/tls/openssl/gtlsconnection-openssl.c b/tls/openssl/gtlsconnection-openssl.c
index 0607f55..64cbcb5 100644
--- a/tls/openssl/gtlsconnection-openssl.c
+++ b/tls/openssl/gtlsconnection-openssl.c
@@ -163,15 +163,13 @@ end_openssl_io (GTlsConnectionOpenssl *openssl,
return G_TLS_CONNECTION_BASE_ERROR;
}
-#define BEGIN_OPENSSL_IO(openssl, direction, blocking, cancellable, operation) \
- g_message("start: %s", operation); \
+#define BEGIN_OPENSSL_IO(openssl, direction, blocking, cancellable) \
g_tls_connection_base_push_io (G_TLS_CONNECTION_BASE (openssl), \
direction, blocking, cancellable); \
do {
-#define END_OPENSSL_IO(openssl, direction, ret, status, errmsg, err, operation) \
+#define END_OPENSSL_IO(openssl, direction, ret, status, errmsg, err) \
status = end_openssl_io (openssl, direction, ret, err, errmsg, ERR_error_string (SSL_get_error (ssl,
ret), NULL)); \
- g_message("end: %s", operation); \
} while (status == G_TLS_CONNECTION_BASE_TRY_AGAIN);
static GTlsConnectionBaseStatus
@@ -195,10 +193,10 @@ g_tls_connection_openssl_request_rehandshake (GTlsConnectionBase *tls,
ssl = g_tls_connection_openssl_get_ssl (openssl);
- BEGIN_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, TRUE, cancellable, "request rehandshake");
+ BEGIN_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, TRUE, cancellable);
ret = SSL_renegotiate (ssl);
END_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, ret, status,
- _("Error performing TLS handshake: %s"), error, "request rehandshake");
+ _("Error performing TLS handshake: %s"), error);
return status;
}
@@ -291,10 +289,10 @@ g_tls_connection_openssl_handshake (GTlsConnectionBase *tls,
ssl = g_tls_connection_openssl_get_ssl (openssl);
- BEGIN_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, TRUE, cancellable, "rehandshake");
+ BEGIN_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, TRUE, cancellable);
ret = SSL_do_handshake (ssl);
END_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, ret, status,
- _("Error performing TLS handshake: %s"), error, "rehandshake");
+ _("Error performing TLS handshake: %s"), error);
if (ret > 0)
{
@@ -365,7 +363,6 @@ g_tls_connection_openssl_push_io (GTlsConnectionBase *tls,
g_tls_bio_set_read_cancellable (priv->bio, cancellable);
g_tls_bio_set_read_blocking (priv->bio, blocking);
g_clear_error (&tls->read_error);
- g_tls_bio_set_read_error (priv->bio, &tls->read_error);
}
if (direction & G_IO_OUT)
@@ -373,7 +370,6 @@ g_tls_connection_openssl_push_io (GTlsConnectionBase *tls,
g_tls_bio_set_write_cancellable (priv->bio, cancellable);
g_tls_bio_set_write_blocking (priv->bio, blocking);
g_clear_error (&tls->write_error);
- g_tls_bio_set_write_error (priv->bio, &tls->write_error);
}
}
@@ -398,6 +394,21 @@ g_tls_connection_openssl_pop_io (GTlsConnectionBase *tls,
success, error);
}
+static void
+convert_code_to_io_error(int code,
+ GError **error)
+{
+ if (code == -G_IO_ERROR_WOULD_BLOCK)
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
+ "Operation would block");
+ else if (code == -G_IO_ERROR_TIMED_OUT)
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT,
+ "Operation timed out");
+ else
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Operation failed");
+}
+
static GTlsConnectionBaseStatus
g_tls_connection_openssl_read (GTlsConnectionBase *tls,
void *buffer,
@@ -414,10 +425,13 @@ g_tls_connection_openssl_read (GTlsConnectionBase *tls,
ssl = g_tls_connection_openssl_get_ssl (openssl);
- BEGIN_OPENSSL_IO (openssl, G_IO_IN, blocking, cancellable, "read");
+ BEGIN_OPENSSL_IO (openssl, G_IO_IN, blocking, cancellable);
ret = SSL_read (ssl, buffer, count);
+ if (ret < 0) {
+ convert_code_to_io_error(ret, &tls->read_error);
+ }
END_OPENSSL_IO (openssl, G_IO_IN, ret, status,
- _("Error reading data from TLS socket: %s"), error, "read");
+ _("Error reading data from TLS socket: %s"), error);
if (ret >= 0)
*nread = ret;
@@ -440,10 +454,13 @@ g_tls_connection_openssl_write (GTlsConnectionBase *tls,
ssl = g_tls_connection_openssl_get_ssl (openssl);
- BEGIN_OPENSSL_IO (openssl, G_IO_OUT, blocking, cancellable, "write");
+ BEGIN_OPENSSL_IO (openssl, G_IO_OUT, blocking, cancellable);
ret = SSL_write (ssl, buffer, count);
+ if (ret < 0) {
+ convert_code_to_io_error(ret, &tls->write_error);
+ }
END_OPENSSL_IO (openssl, G_IO_OUT, ret, status,
- _("Error writing data to TLS socket: %s"), error, "write");
+ _("Error writing data to TLS socket: %s"), error);
if (ret >= 0)
*nwrote = ret;
@@ -466,10 +483,13 @@ g_tls_connection_openssl_close (GTlsConnectionBase *tls,
priv->shutting_down = TRUE;
- BEGIN_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, TRUE, cancellable, "close");
+ BEGIN_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, TRUE, cancellable);
ret = SSL_shutdown (ssl);
+ if (ret < 0) {
+ convert_code_to_io_error(ret, &tls->read_error);
+ }
END_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, ret, status,
- _("Error performing TLS close: %s"), error, "close");
+ _("Error performing TLS close: %s"), error);
return status;
}
@@ -513,6 +533,8 @@ g_tls_connection_openssl_initable_init (GInitable *initable,
priv->bio = g_tls_bio_new (tls->base_io_stream);
SSL_set_bio (ssl, priv->bio, priv->bio);
+ SSL_set_mode (ssl, SSL_MODE_ENABLE_PARTIAL_WRITE |
+ SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]