[glib-networking/mcatanzaro/base-rebase: 8/45] base: Implement vectored I/O support for TLS and DTLS
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking/mcatanzaro/base-rebase: 8/45] base: Implement vectored I/O support for TLS and DTLS
- Date: Mon, 13 May 2019 16:55:39 +0000 (UTC)
commit 9230b4f3cfbcbb62a91e821d1515a2b6720db92a
Author: Michael Catanzaro <mcatanzaro igalia com>
Date: Thu Apr 4 21:20:19 2019 -0500
base: Implement vectored I/O support for TLS and DTLS
Port of eb38088a6c73bad0cff178c38d2545bed3d3ba4a
tls/base/gtlsconnection-base.c | 111 +++++++++++++++++++++++++++++++++--------
tls/base/gtlsconnection-base.h | 15 ++++++
2 files changed, 105 insertions(+), 21 deletions(-)
---
diff --git a/tls/base/gtlsconnection-base.c b/tls/base/gtlsconnection-base.c
index 4aa5701..46ff295 100644
--- a/tls/base/gtlsconnection-base.c
+++ b/tls/base/gtlsconnection-base.c
@@ -1312,6 +1312,57 @@ g_tls_connection_base_read (GTlsConnectionBase *tls,
return -1;
}
+static gssize
+g_tls_connection_base_read_message (GTlsConnectionBase *tls,
+ GInputVector *vectors,
+ guint num_vectors,
+ gint64 timeout,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GTlsConnectionBaseStatus status;
+ gssize nread;
+
+ do {
+ if (!claim_op (tls, G_TLS_CONNECTION_BASE_OP_READ,
+ timeout != 0, cancellable, error))
+ return -1;
+
+ /* Copy data out of the app data buffer first. */
+ if (tls->app_data_buf && !tls->handshaking)
+ {
+ nread = 0;
+
+ for (guint i = 0; i < num_vectors; i++)
+ {
+ gsize count;
+ GInputVector *vec = &vectors[i];
+
+ count = MIN (vec->size, tls->app_data_buf->len);
+ nread += count;
+
+ memcpy (vec->buffer, tls->app_data_buf->data, count);
+ if (count == tls->app_data_buf->len)
+ g_clear_pointer (&tls->app_data_buf, g_byte_array_unref);
+ else
+ g_byte_array_remove_range (tls->app_data_buf, 0, count);
+ status = G_TLS_CONNECTION_BASE_OK;
+ }
+ }
+ else
+ {
+ status = G_TLS_CONNECTION_BASE_GET_CLASS (tls)->
+ read_message_fn (tls, vectors, num_vectors, timeout, &nread, cancellable, error);
+ }
+
+ yield_op (tls, G_TLS_CONNECTION_BASE_OP_READ, status);
+ } while (status == G_TLS_CONNECTION_BASE_REHANDSHAKE);
+
+ if (status == G_TLS_CONNECTION_BASE_OK)
+ return nread;
+ return -1;
+}
+
static gint
g_tls_connection_base_receive_messages (GDatagramBased *datagram_based,
GInputMessage *messages,
@@ -1339,16 +1390,12 @@ g_tls_connection_base_receive_messages (GDatagramBased *datagram_based,
GInputMessage *message = &messages[i];
gssize n_bytes_read;
- /* FIXME: Unfortunately GnuTLS doesn’t have a vectored read function.
- * See: https://gitlab.com/gnutls/gnutls/issues/16 */
- g_assert (message->num_vectors == 1);
-
- n_bytes_read = g_tls_connection_base_read (tls,
- message->vectors[0].buffer,
- message->vectors[0].size,
- timeout != 0,
- cancellable,
- &child_error);
+ n_bytes_read = g_tls_connection_base_read_message (tls,
+ message->vectors,
+ message->num_vectors,
+ timeout,
+ cancellable,
+ &child_error);
if (message->address != NULL)
*message->address = NULL;
@@ -1423,6 +1470,33 @@ g_tls_connection_base_write (GTlsConnectionBase *tls,
return -1;
}
+static gssize
+g_tls_connection_base_write_message (GTlsConnectionBase *tls,
+ GOutputVector *vectors,
+ guint num_vectors,
+ gint64 timeout,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GTlsConnectionBaseStatus status;
+ gssize nwrote;
+
+ do {
+ if (!claim_op (tls, G_TLS_CONNECTION_BASE_OP_WRITE,
+ timeout != 0, cancellable, error))
+ return -1;
+
+ status = G_TLS_CONNECTION_BASE_GET_CLASS (tls)->
+ write_message_fn (tls, vectors, num_vectors, timeout, &nwrote, cancellable, error);
+
+ yield_op (tls, G_TLS_CONNECTION_BASE_OP_WRITE, status);
+ } while (status == G_TLS_CONNECTION_BASE_REHANDSHAKE);
+
+ if (status == G_TLS_CONNECTION_BASE_OK)
+ return nwrote;
+ return -1;
+}
+
static gint
g_tls_connection_base_send_messages (GDatagramBased *datagram_based,
GOutputMessage *messages,
@@ -1450,17 +1524,12 @@ g_tls_connection_base_send_messages (GDatagramBased *datagram_based,
GOutputMessage *message = &messages[i];
gssize n_bytes_sent;
- /* FIXME: Unfortunately GnuTLS doesn’t have a vectored write function.
- * See: https://gitlab.com/gnutls/gnutls/issues/16 */
- /* TODO: gnutls_record_cork(), gnutls_record_uncork(), 3.3.0 */
- g_assert (message->num_vectors == 1);
-
- n_bytes_sent = g_tls_connection_base_write (tls,
- message->vectors[0].buffer,
- message->vectors[0].size,
- timeout != 0,
- cancellable,
- &child_error);
+ n_bytes_sent = g_tls_connection_base_write_message (tls,
+ message->vectors,
+ message->num_vectors,
+ timeout,
+ cancellable,
+ &child_error);
if (n_bytes_sent >= 0)
{
diff --git a/tls/base/gtlsconnection-base.h b/tls/base/gtlsconnection-base.h
index 8a616aa..60e09cd 100644
--- a/tls/base/gtlsconnection-base.h
+++ b/tls/base/gtlsconnection-base.h
@@ -78,6 +78,14 @@ struct _GTlsConnectionBaseClass
gssize *nread,
GCancellable *cancellable,
GError **error);
+ GTlsConnectionBaseStatus (*read_message_fn) (GTlsConnectionBase *tls,
+ GInputVector *vectors,
+ guint num_vectors,
+ gint64 timeout,
+ gssize *nread,
+ GCancellable *cancellable,
+ GError **error);
+
GTlsConnectionBaseStatus (*write_fn) (GTlsConnectionBase *tls,
const void *buffer,
gsize count,
@@ -85,6 +93,13 @@ struct _GTlsConnectionBaseClass
gssize *nwrote,
GCancellable *cancellable,
GError **error);
+ GTlsConnectionBaseStatus (*write_message_fn) (GTlsConnectionBase *tls,
+ GOutputVector *vectors,
+ guint num_vectors,
+ gint64 timeout,
+ gssize *nwrote,
+ GCancellable *cancellable,
+ GError **error);
GTlsConnectionBaseStatus (*close_fn) (GTlsConnectionBase *tls,
GCancellable *cancellable,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]