[glib-networking/mcatanzaro/tls-thread] progress
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking/mcatanzaro/tls-thread] progress
- Date: Mon, 16 Dec 2019 01:52:18 +0000 (UTC)
commit be2b17e312c8fb3190ab1567631d0c06bb6c1292
Author: Michael Catanzaro <mcatanzaro gnome org>
Date: Sun Dec 15 19:52:14 2019 -0600
progress
tls/base/gtlsconnection-base.c | 3 +-
tls/base/gtlsconnection-base.h | 8 +-
tls/base/gtlsoperationsthread-base.c | 197 ++++++++++++++++++++++-------
tls/base/gtlsoperationsthread-base.h | 8 ++
tls/gnutls/gtlsconnection-gnutls.c | 19 ---
tls/gnutls/gtlsoperationsthread-gnutls.c | 17 +++
tls/openssl/gtlsconnection-openssl.c | 48 +------
tls/openssl/gtlsconnection-openssl.h | 5 +-
tls/openssl/gtlsoperationsthread-openssl.c | 29 ++++-
9 files changed, 208 insertions(+), 126 deletions(-)
---
diff --git a/tls/base/gtlsconnection-base.c b/tls/base/gtlsconnection-base.c
index d9f8c4b..406a31d 100644
--- a/tls/base/gtlsconnection-base.c
+++ b/tls/base/gtlsconnection-base.c
@@ -2333,8 +2333,7 @@ g_tls_connection_base_close_internal (GIOStream *stream,
if (priv->ever_handshaked && !priv->write_closed &&
direction & G_TLS_DIRECTION_WRITE)
{
- status = G_TLS_CONNECTION_BASE_GET_CLASS (tls)->
- close_fn (tls, timeout, cancellable, &close_error);
+ status = g_tls_operations_thread_base_close (priv->thread, cancellable, &close_error);
priv->write_closed = TRUE;
}
diff --git a/tls/base/gtlsconnection-base.h b/tls/base/gtlsconnection-base.h
index 33a89ec..5e89b09 100644
--- a/tls/base/gtlsconnection-base.h
+++ b/tls/base/gtlsconnection-base.h
@@ -40,7 +40,7 @@ typedef enum {
G_TLS_CONNECTION_BASE_REHANDSHAKE,
G_TLS_CONNECTION_BASE_TRY_AGAIN,
G_TLS_CONNECTION_BASE_ERROR,
-} GTlsConnectionBaseStatus;
+} GTlsConnectionBaseStatus; /* FIXME: move? rename? GTlsOperationsThreadBaseStatus */
typedef enum {
G_TLS_DIRECTION_NONE = 0,
@@ -94,12 +94,6 @@ struct _GTlsConnectionBaseClass
GIOCondition direction,
gboolean success,
GError **error);
-
- /* FIXME: must remove timeout parameters from all vfuncs, including handshake vfuncs */
- GTlsConnectionBaseStatus (*close_fn) (GTlsConnectionBase *tls,
- gint64 timeout,
- GCancellable *cancellable,
- GError **error);
};
gboolean g_tls_connection_base_handshake_thread_verify_certificate
diff --git a/tls/base/gtlsoperationsthread-base.c b/tls/base/gtlsoperationsthread-base.c
index 05e2140..85db976 100644
--- a/tls/base/gtlsoperationsthread-base.c
+++ b/tls/base/gtlsoperationsthread-base.c
@@ -82,10 +82,8 @@ typedef enum {
G_TLS_THREAD_OP_READ_MESSAGE,
G_TLS_THREAD_OP_WRITE,
G_TLS_THREAD_OP_WRITE_MESSAGE,
- G_TLS_THREAD_OP_CLOSE_READ,
- G_TLS_THREAD_OP_CLOSE_WRITE,
- G_TLS_THREAD_OP_CLOSE_BOTH,
- G_TLS_THREAD_OP_SHUTDOWN /* FIXME: redundant with CLOSE_BOTH op? */
+ G_TLS_THREAD_OP_CLOSE,
+ G_TLS_THREAD_OP_SHUTDOWN_THREAD
} GTlsThreadOperationType;
typedef struct {
@@ -95,21 +93,26 @@ typedef struct {
GTlsOperationsThreadBase *thread;
GTlsConnectionBase *connection; /* FIXME: threadsafety nightmare, not OK */
- /* Input */
union {
void *data;
GInputVector *input_vectors;
GOutputVector *output_vectors;
} /* unowned */;
+
union {
gsize size; /* for non-vectored data buffer */
guint num_vectors;
};
+
gint64 timeout;
gint64 start_time;
+
GCancellable *cancellable;
- /* Used to indicate op completion. */
+ /* Async ops */
+ GTask *task;
+
+ /* Sync ops */
GMutex finished_mutex;
GCond finished_condition;
gboolean finished;
@@ -162,15 +165,13 @@ g_tls_thread_operation_new (GTlsThreadOperationType type,
{
case G_TLS_THREAD_OP_READ:
/* fallthrough */
- case G_TLS_THREAD_OP_CLOSE_READ:
op->io_condition = G_IO_IN;
break;
case G_TLS_THREAD_OP_WRITE:
/* fallthrough */
- case G_TLS_THREAD_OP_CLOSE_WRITE:
op->io_condition = G_IO_OUT;
break;
- case G_TLS_THREAD_OP_CLOSE_BOTH:
+ case G_TLS_THREAD_OP_CLOSE:
op->io_condition = G_IO_IN | G_IO_OUT;
break;
default:
@@ -181,8 +182,32 @@ g_tls_thread_operation_new (GTlsThreadOperationType type,
}
static GTlsThreadOperation *
-g_tls_thread_operation_new_with_input_vectors (GTlsThreadOperationType type,
- GTlsOperationsThreadBase *thread,
+g_tls_thread_operation_new_async (GTlsThreadOperationType type,
+ GTlsOperationsThreadBase *thread,
+ GTlsConnectionBase *connection,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTlsThreadOperation *op;
+
+ op = g_new0 (GTlsThreadOperation, 1);
+ op->type = type;
+ op->thread = thread; /* FIXME: use a weak ref? */
+ op->connection = g_object_ref (connection);
+ op->timeout = -1 /* blocking on the thread */;
+ op->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
+
+ g_assert (type == G_TLS_THREAD_OP_CLOSE /* FIXME: || type == G_TLS_THREAD_OP_HANDSHAKE*/);
+ op->io_condition = G_IO_IN | G_IO_OUT;
+
+ op->task = g_task_new (thread, cancellable, callback, user_data);
+
+ return op;
+}
+
+static GTlsThreadOperation *
+g_tls_thread_operation_new_with_input_vectors (GTlsOperationsThreadBase *thread,
GTlsConnectionBase *connection,
GInputVector *vectors,
guint num_vectors,
@@ -191,10 +216,8 @@ g_tls_thread_operation_new_with_input_vectors (GTlsThreadOperationType type,
{
GTlsThreadOperation *op;
- g_assert (type == G_TLS_THREAD_OP_READ_MESSAGE);
-
op = g_new0 (GTlsThreadOperation, 1);
- op->type = type;
+ op->type = G_TLS_THREAD_OP_READ_MESSAGE;
op->io_condition = G_IO_IN;
op->thread = thread; /* FIXME: use a weak ref? */
op->connection = g_object_ref (connection);
@@ -210,8 +233,7 @@ g_tls_thread_operation_new_with_input_vectors (GTlsThreadOperationType type,
}
static GTlsThreadOperation *
-g_tls_thread_operation_new_with_output_vectors (GTlsThreadOperationType type,
- GTlsOperationsThreadBase *thread,
+g_tls_thread_operation_new_with_output_vectors (GTlsOperationsThreadBase *thread,
GTlsConnectionBase *connection,
GOutputVector *vectors,
guint num_vectors,
@@ -220,10 +242,8 @@ g_tls_thread_operation_new_with_output_vectors (GTlsThreadOperationType type,
{
GTlsThreadOperation *op;
- g_assert (type == G_TLS_THREAD_OP_WRITE_MESSAGE);
-
op = g_new0 (GTlsThreadOperation, 1);
- op->type = type;
+ op->type = G_TLS_THREAD_OP_WRITE_MESSAGE;
op->io_condition = G_IO_OUT;
op->thread = thread; /* FIXME: use a weak ref? */
op->connection = g_object_ref (connection);
@@ -244,7 +264,7 @@ g_tls_thread_shutdown_operation_new (void)
GTlsThreadOperation *op;
op = g_new0 (GTlsThreadOperation, 1);
- op->type = G_TLS_THREAD_OP_SHUTDOWN;
+ op->type = G_TLS_THREAD_OP_SHUTDOWN_THREAD;
return op;
}
@@ -255,7 +275,7 @@ g_tls_thread_operation_free (GTlsThreadOperation *op)
g_clear_object (&op->connection);
g_clear_object (&op->cancellable);
- if (op->type != G_TLS_THREAD_OP_SHUTDOWN)
+ if (op->type != G_TLS_THREAD_OP_SHUTDOWN_THREAD)
{
g_mutex_clear (&op->finished_mutex);
g_cond_clear (&op->finished_condition);
@@ -282,21 +302,26 @@ g_tls_operations_thread_base_get_connection (GTlsOperationsThreadBase *self)
}
static GTlsConnectionBaseStatus
-execute_op (GTlsOperationsThreadBase *self,
- GTlsThreadOperation *op /* owned */,
- gssize *count,
- GError **error)
+execute_sync_op (GTlsOperationsThreadBase *self,
+ GTlsThreadOperation *op /* owned */,
+ gssize *count,
+ GError **error)
{
GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
GTlsConnectionBaseStatus result;
+ g_assert (!op->task);
+
g_async_queue_push (priv->queue, op);
g_main_context_wakeup (priv->op_thread_context);
wait_for_op_completion (op);
- *count = op->count;
+ if (count)
+ *count = op->count;
+
result = op->result;
+
if (op->error)
{
g_propagate_error (error, op->error);
@@ -308,6 +333,18 @@ execute_op (GTlsOperationsThreadBase *self,
return result;
}
+static void
+execute_async_op (GTlsOperationsThreadBase *self,
+ GTlsThreadOperation *op)
+{
+ GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
+
+ g_assert (op->task);
+
+ g_async_queue_push (priv->queue, g_steal_pointer (&op));
+ g_main_context_wakeup (priv->op_thread_context);
+}
+
GTlsConnectionBaseStatus
g_tls_operations_thread_base_read (GTlsOperationsThreadBase *self,
void *buffer,
@@ -323,10 +360,11 @@ g_tls_operations_thread_base_read (GTlsOperationsThreadBase *self,
op = g_tls_thread_operation_new (G_TLS_THREAD_OP_READ,
self,
priv->connection,
- buffer, size, timeout,
+ buffer, size,
+ timeout,
cancellable);
- return execute_op (self, g_steal_pointer (&op), nread, error);
+ return execute_sync_op (self, g_steal_pointer (&op), nread, error);
}
GTlsConnectionBaseStatus
@@ -341,13 +379,13 @@ g_tls_operations_thread_base_read_message (GTlsOperationsThreadBase *self,
GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
GTlsThreadOperation *op;
- op = g_tls_thread_operation_new_with_input_vectors (G_TLS_THREAD_OP_READ_MESSAGE,
- self,
+ op = g_tls_thread_operation_new_with_input_vectors (self,
priv->connection,
- vectors, num_vectors, timeout,
+ vectors, num_vectors,
+ timeout,
cancellable);
- return execute_op (self, g_steal_pointer (&op), nread, error);
+ return execute_sync_op (self, g_steal_pointer (&op), nread, error);
}
GTlsConnectionBaseStatus
@@ -365,10 +403,11 @@ g_tls_operations_thread_base_write (GTlsOperationsThreadBase *self,
op = g_tls_thread_operation_new (G_TLS_THREAD_OP_WRITE,
self,
priv->connection,
- (void *)buffer, size, timeout,
+ (void *)buffer, size,
+ timeout,
cancellable);
- return execute_op (self, g_steal_pointer (&op), nwrote, error);
+ return execute_sync_op (self, g_steal_pointer (&op), nwrote, error);
}
GTlsConnectionBaseStatus
@@ -383,15 +422,66 @@ g_tls_operations_thread_base_write_message (GTlsOperationsThreadBase *self,
GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
GTlsThreadOperation *op;
- op = g_tls_thread_operation_new_with_output_vectors (G_TLS_THREAD_OP_WRITE_MESSAGE,
- self,
+ op = g_tls_thread_operation_new_with_output_vectors (self,
priv->connection,
- vectors, num_vectors, timeout,
+ vectors, num_vectors,
+ timeout,
cancellable);
- return execute_op (self, g_steal_pointer (&op), nwrote, error);
+ return execute_sync_op (self, g_steal_pointer (&op), nwrote, error);
}
+GTlsConnectionBaseStatus
+g_tls_operations_thread_base_close (GTlsOperationsThreadBase *self,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
+ GTlsThreadOperation *op;
+
+ op = g_tls_thread_operation_new (G_TLS_THREAD_OP_CLOSE,
+ self,
+ priv->connection,
+ NULL, 0,
+ -1 /* blocking */,
+ cancellable);
+
+ return execute_sync_op (self, g_steal_pointer (&op), NULL, error);
+}
+
+#if 0
+FIXME: needs removed, but good template for handshake?
+
+void
+g_tls_operations_thread_base_close_async (GTlsOperationsThreadBase *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
+ GTlsThreadOperation *op;
+
+ op = g_tls_thread_operation_new_async (G_TLS_THREAD_OP_CLOSE,
+ self,
+ priv->connection,
+ cancellable,
+ callback,
+ user_data);
+
+ return execute_async_op (self, g_steal_pointer (&op));
+}
+
+GTlsConnectionBaseStatus
+g_tls_operations_thread_base_close_finish (GTlsOperationsThreadBase *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_assert (g_task_is_valid (result, self));
+
+ return g_task_propagate_int (G_TASK (result), error);
+}
+#endif
+
typedef struct {
GSource source;
@@ -688,7 +778,7 @@ process_op (GAsyncQueue *queue,
op = g_async_queue_try_pop (queue);
g_assert (op);
- if (op->type == G_TLS_THREAD_OP_SHUTDOWN)
+ if (op->type == G_TLS_THREAD_OP_SHUTDOWN_THREAD)
{
g_main_loop_quit (main_loop);
return G_SOURCE_REMOVE;
@@ -697,7 +787,7 @@ process_op (GAsyncQueue *queue,
adjust_op_timeout (op);
}
- if (op->type != G_TLS_THREAD_OP_SHUTDOWN)
+ if (op->type != G_TLS_THREAD_OP_SHUTDOWN_THREAD)
{
g_assert (op->thread);
base_class = G_TLS_OPERATIONS_THREAD_BASE_GET_CLASS (op->thread);
@@ -705,7 +795,6 @@ process_op (GAsyncQueue *queue,
switch (op->type)
{
- /* FIXME: handle all op types, including handshake and directional closes */
case G_TLS_THREAD_OP_READ:
g_assert (base_class->read_fn);
op->result = base_class->read_fn (op->thread,
@@ -738,7 +827,13 @@ process_op (GAsyncQueue *queue,
op->cancellable,
&op->error);
break;
- case G_TLS_THREAD_OP_SHUTDOWN:
+ case G_TLS_THREAD_OP_CLOSE:
+ g_assert (base_class->close_fn);
+ op->result = base_class->close_fn (op->thread,
+ op->cancellable,
+ &op->error);
+ break;
+ case G_TLS_THREAD_OP_SHUTDOWN_THREAD:
g_assert_not_reached ();
}
@@ -781,10 +876,20 @@ wait:
}
finished:
- g_mutex_lock (&op->finished_mutex);
- op->finished = TRUE;
- g_cond_signal (&op->finished_condition);
- g_mutex_unlock (&op->finished_mutex);
+ if (op->task) /* async op */
+ {
+ if (op->error)
+ g_task_return_error (op->task, op->error);
+ else
+ g_task_return_int (op->task, op->result);
+ }
+ else /* sync op */
+ {
+ g_mutex_lock (&op->finished_mutex);
+ op->finished = TRUE;
+ g_cond_signal (&op->finished_condition);
+ g_mutex_unlock (&op->finished_mutex);
+ }
return G_SOURCE_CONTINUE;
}
diff --git a/tls/base/gtlsoperationsthread-base.h b/tls/base/gtlsoperationsthread-base.h
index f2fea94..ea99778 100644
--- a/tls/base/gtlsoperationsthread-base.h
+++ b/tls/base/gtlsoperationsthread-base.h
@@ -63,6 +63,10 @@ struct _GTlsOperationsThreadBaseClass
gssize *nwrote,
GCancellable *cancellable,
GError **error);
+
+ GTlsConnectionBaseStatus (*close_fn) (GTlsOperationsThreadBase *tls,
+ GCancellable *cancellable,
+ GError **error);
};
/* FIXME: remove? */
@@ -100,4 +104,8 @@ GTlsConnectionBaseStatus g_tls_operations_thread_base_write_message (GTlsOpera
GCancellable
*cancellable,
GError **error);
+GTlsConnectionBaseStatus g_tls_operations_thread_base_close (GTlsOperationsThreadBase *self,
+ GCancellable
*cancellable,
+ GError **error);
+
G_END_DECLS
diff --git a/tls/gnutls/gtlsconnection-gnutls.c b/tls/gnutls/gtlsconnection-gnutls.c
index 508892c..3bccc98 100644
--- a/tls/gnutls/gtlsconnection-gnutls.c
+++ b/tls/gnutls/gtlsconnection-gnutls.c
@@ -929,24 +929,6 @@ g_tls_connection_gnutls_is_session_resumed (GTlsConnectionBase *tls)
return gnutls_session_is_resumed (priv->session);
}
-static GTlsConnectionBaseStatus
-g_tls_connection_gnutls_close (GTlsConnectionBase *tls,
- gint64 timeout,
- GCancellable *cancellable,
- GError **error)
-{
- GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (tls);
- GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
- GTlsConnectionBaseStatus status;
- int ret;
-
- BEGIN_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, timeout, cancellable);
- ret = gnutls_bye (priv->session, GNUTLS_SHUT_WR);
- END_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, ret, status, _("Error performing TLS close: %s"), error);
-
- return status;
-}
-
static void
initialize_gnutls_priority (void)
{
@@ -986,7 +968,6 @@ g_tls_connection_gnutls_class_init (GTlsConnectionGnutlsClass *klass)
base_class->retrieve_peer_certificate = g_tls_connection_gnutls_retrieve_peer_certificate;
base_class->complete_handshake = g_tls_connection_gnutls_complete_handshake;
base_class->is_session_resumed = g_tls_connection_gnutls_is_session_resumed;
- base_class->close_fn = g_tls_connection_gnutls_close;
initialize_gnutls_priority ();
}
diff --git a/tls/gnutls/gtlsoperationsthread-gnutls.c b/tls/gnutls/gtlsoperationsthread-gnutls.c
index 1ac7e56..7920e4d 100644
--- a/tls/gnutls/gtlsoperationsthread-gnutls.c
+++ b/tls/gnutls/gtlsoperationsthread-gnutls.c
@@ -363,6 +363,22 @@ g_tls_operations_thread_gnutls_write_message (GTlsOperationsThreadBase *base,
return status;
}
+static GTlsConnectionBaseStatus
+g_tls_operations_thread_gnutls_close (GTlsOperationsThreadBase *base,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GTlsOperationsThreadGnutls *self = G_TLS_OPERATIONS_THREAD_GNUTLS (base);
+ GTlsConnectionBaseStatus status;
+ int ret;
+
+ BEGIN_GNUTLS_IO (self, G_IO_IN | G_IO_OUT, cancellable);
+ ret = gnutls_bye (self->session, GNUTLS_SHUT_WR);
+ END_GNUTLS_IO (self, G_IO_IN | G_IO_OUT, ret, status, _("Error performing TLS close: %s"), error);
+
+ return status;
+}
+
static void
g_tls_operations_thread_gnutls_constructed (GObject *object)
{
@@ -392,6 +408,7 @@ g_tls_operations_thread_gnutls_class_init (GTlsOperationsThreadGnutlsClass *klas
base_class->read_message_fn = g_tls_operations_thread_gnutls_read_message;
base_class->write_fn = g_tls_operations_thread_gnutls_write;
base_class->write_message_fn = g_tls_operations_thread_gnutls_write_message;
+ base_class->close_fn = g_tls_operations_thread_gnutls_close;
}
GTlsOperationsThreadBase *
diff --git a/tls/openssl/gtlsconnection-openssl.c b/tls/openssl/gtlsconnection-openssl.c
index af85e45..b06465e 100644
--- a/tls/openssl/gtlsconnection-openssl.c
+++ b/tls/openssl/gtlsconnection-openssl.c
@@ -42,8 +42,6 @@
typedef struct _GTlsConnectionOpensslPrivate
{
BIO *bio;
-
- gboolean shutting_down;
} GTlsConnectionOpensslPrivate;
static GInitableIface *g_tls_connection_openssl_parent_initable_iface;
@@ -83,14 +81,11 @@ end_openssl_io (GTlsConnectionOpenssl *openssl,
const char *err_str)
{
GTlsConnectionBase *tls = G_TLS_CONNECTION_BASE (openssl);
- GTlsConnectionOpensslPrivate *priv;
int err_code, err, err_lib, reason;
GError *my_error = NULL;
GTlsConnectionBaseStatus status;
SSL *ssl;
- priv = g_tls_connection_openssl_get_instance_private (openssl);
-
ssl = g_tls_connection_openssl_get_ssl (openssl);
err_code = SSL_get_error (ssl, ret);
@@ -119,9 +114,9 @@ end_openssl_io (GTlsConnectionOpenssl *openssl,
}
/* This case is documented that it may happen and that is perfectly fine */
+ /* FIXME: broke this, but entire func should be deleted so OK */
if (err_code == SSL_ERROR_SYSCALL &&
- ((priv->shutting_down && !my_error) ||
- g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE)))
+ g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE))
{
g_clear_error (&my_error);
return G_TLS_CONNECTION_BASE_OK;
@@ -363,44 +358,6 @@ g_tls_connection_openssl_pop_io (GTlsConnectionBase *tls,
success, error);
}
-static GTlsConnectionBaseStatus
-g_tls_connection_openssl_close (GTlsConnectionBase *tls,
- gint64 timeout,
- GCancellable *cancellable,
- GError **error)
-{
- GTlsConnectionOpenssl *openssl = G_TLS_CONNECTION_OPENSSL (tls);
- GTlsConnectionOpensslPrivate *priv;
- GTlsConnectionBaseStatus status;
- SSL *ssl;
- int ret;
-
- ssl = g_tls_connection_openssl_get_ssl (openssl);
- priv = g_tls_connection_openssl_get_instance_private (openssl);
-
- priv->shutting_down = TRUE;
-
- BEGIN_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, timeout, cancellable);
- ret = SSL_shutdown (ssl);
- /* Note it is documented that getting 0 is correct when shutting down since
- * it means it will close the write direction
- */
- ret = ret == 0 ? 1 : ret;
- END_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, ret, timeout, status,
- _("Error performing TLS close"), error);
-
- return status;
-}
-
-/* FIXME: remove */
-gboolean
-g_tls_connection_openssl_get_shutting_down (GTlsConnectionOpenssl *openssl)
-{
- GTlsConnectionOpensslPrivate *priv = g_tls_connection_openssl_get_instance_private (openssl);
-
- return priv->shutting_down;
-}
-
static void
g_tls_connection_openssl_class_init (GTlsConnectionOpensslClass *klass)
{
@@ -413,7 +370,6 @@ g_tls_connection_openssl_class_init (GTlsConnectionOpensslClass *klass)
base_class->retrieve_peer_certificate =
g_tls_connection_openssl_retrieve_peer_certificate;
base_class->push_io = g_tls_connection_openssl_push_io;
base_class->pop_io = g_tls_connection_openssl_pop_io;
- base_class->close_fn = g_tls_connection_openssl_close;
}
static int data_index = -1;
diff --git a/tls/openssl/gtlsconnection-openssl.h b/tls/openssl/gtlsconnection-openssl.h
index c5aca9c..10f93c3 100644
--- a/tls/openssl/gtlsconnection-openssl.h
+++ b/tls/openssl/gtlsconnection-openssl.h
@@ -40,14 +40,11 @@ struct _GTlsConnectionOpensslClass
{
GTlsConnectionBaseClass parent_class;
- SSL *(*get_ssl) (GTlsConnectionOpenssl *connection);
+ SSL *(*get_ssl) (GTlsConnectionOpenssl *connection);
};
SSL *g_tls_connection_openssl_get_ssl (GTlsConnectionOpenssl *connection);
GTlsConnectionOpenssl *g_tls_connection_openssl_get_connection_from_ssl (SSL *ssl);
-/* FIXME: remove */
-gboolean g_tls_connection_openssl_get_shutting_down (GTlsConnectionOpenssl *connection);
-
G_END_DECLS
diff --git a/tls/openssl/gtlsoperationsthread-openssl.c b/tls/openssl/gtlsoperationsthread-openssl.c
index 9e5fa60..d7ecc0b 100644
--- a/tls/openssl/gtlsoperationsthread-openssl.c
+++ b/tls/openssl/gtlsoperationsthread-openssl.c
@@ -35,6 +35,8 @@ struct _GTlsOperationsThreadOpenssl {
GTlsOperationsThreadBase parent_instance;
SSL *ssl;
+
+ gboolean shutting_down;
};
G_DEFINE_TYPE (GTlsOperationsThreadOpenssl, g_tls_operations_thread_openssl,
G_TYPE_TLS_OPERATIONS_THREAD_BASE)
@@ -72,8 +74,7 @@ end_openssl_io (GTlsOperationsThreadOpenssl *self,
/* This case is documented that it may happen and that is perfectly fine */
if (err_code == SSL_ERROR_SYSCALL &&
- ((g_tls_connection_openssl_get_shutting_down (G_TLS_CONNECTION_OPENSSL (tls)) && !my_error) ||
- g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE)))
+ ((self->shutting_down && !my_error) || g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE)))
{
g_clear_error (&my_error);
return G_TLS_CONNECTION_BASE_OK;
@@ -213,6 +214,29 @@ g_tls_operations_thread_openssl_write (GTlsOperationsThreadBase *base,
return status;
}
+static GTlsConnectionBaseStatus
+g_tls_operations_thread_openssl_close (GTlsOperationsThreadBase *base,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GTlsOperationsThreadOpenssl *self = G_TLS_OPERATIONS_THREAD_OPENSSL (base);
+ GTlsConnectionBaseStatus status;
+ int ret;
+
+ self->shutting_down = TRUE;
+
+ BEGIN_OPENSSL_IO (self, G_IO_IN | G_IO_OUT, cancellable);
+ ret = SSL_shutdown (self->ssl);
+ /* Note it is documented that getting 0 is correct when shutting down since
+ * it means it will close the write direction
+ */
+ ret = ret == 0 ? 1 : ret;
+ END_OPENSSL_IO (self, G_IO_IN | G_IO_OUT, ret, status,
+ _("Error performing TLS close"), error);
+
+ return status;
+}
+
static void
g_tls_operations_thread_openssl_constructed (GObject *object)
{
@@ -240,6 +264,7 @@ g_tls_operations_thread_openssl_class_init (GTlsOperationsThreadOpensslClass *kl
base_class->read_fn = g_tls_operations_thread_openssl_read;
base_class->write_fn = g_tls_operations_thread_openssl_write;
+ base_class->close_fn = g_tls_operations_thread_openssl_close;
}
GTlsOperationsThreadBase *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]