[glib-networking/wip/pwithnall/dtls: 68/74] gnutls: Implement a vectored push callback function for GnuTLS
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking/wip/pwithnall/dtls: 68/74] gnutls: Implement a vectored push callback function for GnuTLS
- Date: Fri, 13 Oct 2017 12:50:30 +0000 (UTC)
commit 2d653212f1c7d964fc0c4cc1de65629bda71f9d4
Author: Philip Withnall <philip withnall collabora co uk>
Date: Fri Jul 3 18:50:29 2015 +0100
gnutls: Implement a vectored push callback function for GnuTLS
If operating in DTLS mode, this allows GnuTLS to do vectored writes to
the base GDatagramBased, which should improve performance a little.
This is not *required* for DTLS support, as the normal non-vectored push
function also works. It is not implemented for normal TLS as
GOutputStream does not support vectored I/O.
https://bugzilla.gnome.org/show_bug.cgi?id=697908
tls/gnutls/gtlsconnection-gnutls.c | 67 ++++++++++++++++++++++++++++++++++++
1 files changed, 67 insertions(+), 0 deletions(-)
---
diff --git a/tls/gnutls/gtlsconnection-gnutls.c b/tls/gnutls/gtlsconnection-gnutls.c
index 30c0eec..4ec41cd 100644
--- a/tls/gnutls/gtlsconnection-gnutls.c
+++ b/tls/gnutls/gtlsconnection-gnutls.c
@@ -87,6 +87,9 @@
static ssize_t g_tls_connection_gnutls_push_func (gnutls_transport_ptr_t transport_data,
const void *buf,
size_t buflen);
+static ssize_t g_tls_connection_gnutls_vec_push_func (gnutls_transport_ptr_t transport_data,
+ const giovec_t *iov,
+ int iovcnt);
static ssize_t g_tls_connection_gnutls_pull_func (gnutls_transport_ptr_t transport_data,
void *buf,
size_t buflen);
@@ -381,6 +384,13 @@ g_tls_connection_gnutls_initable_init (GInitable *initable,
g_tls_connection_gnutls_pull_timeout_func);
gnutls_transport_set_ptr (gnutls->priv->session, gnutls);
+ /* GDatagramBased supports vectored I/O; GPollableOutputStream does not. */
+ if (gnutls->priv->base_socket != NULL)
+ {
+ gnutls_transport_set_vec_push_function (gnutls->priv->session,
+ g_tls_connection_gnutls_vec_push_func);
+ }
+
/* Create output streams if operating in streaming mode. */
if (!(flags & GNUTLS_DATAGRAM))
{
@@ -1419,6 +1429,63 @@ g_tls_connection_gnutls_push_func (gnutls_transport_ptr_t transport_data,
return ret;
}
+static ssize_t
+g_tls_connection_gnutls_vec_push_func (gnutls_transport_ptr_t transport_data,
+ const giovec_t *iov,
+ int iovcnt)
+{
+ GTlsConnectionGnutls *gnutls = transport_data;
+ ssize_t ret;
+ GOutputMessage message = { NULL, };
+ GOutputVector *vectors;
+
+ /* This function should only be set if we’re using base_socket. */
+ g_assert (gnutls->priv->base_socket != NULL);
+
+ /* See comment in pull_func. */
+ g_clear_error (&gnutls->priv->write_error);
+
+ /* this entire expression will be evaluated at compile time */
+ if (sizeof *iov == sizeof *vectors &&
+ sizeof iov->iov_base == sizeof vectors->buffer &&
+ G_STRUCT_OFFSET (giovec_t, iov_base) ==
+ G_STRUCT_OFFSET (GOutputVector, buffer) &&
+ sizeof iov->iov_len == sizeof vectors->size &&
+ G_STRUCT_OFFSET (giovec_t, iov_len) ==
+ G_STRUCT_OFFSET (GOutputVector, size))
+ /* ABI is compatible */
+ {
+ message.vectors = (GOutputVector *) iov;
+ message.num_vectors = iovcnt;
+ }
+ else
+ /* ABI is incompatible */
+ {
+ gint i;
+
+ message.vectors = g_newa (GOutputVector, iovcnt);
+ for (i = 0; i < iovcnt; i++)
+ {
+ message.vectors[i].buffer = (void *) iov[i].iov_base;
+ message.vectors[i].size = iov[i].iov_len;
+ }
+ message.num_vectors = iovcnt;
+ }
+
+ ret = g_datagram_based_send_messages (gnutls->priv->base_socket,
+ &message, 1, 0,
+ gnutls->priv->write_blocking,
+ gnutls->priv->write_cancellable,
+ &gnutls->priv->write_error);
+
+ if (ret > 0)
+ ret = message.bytes_sent;
+ else if (ret < 0)
+ set_gnutls_error (gnutls, gnutls->priv->write_error);
+
+ return ret;
+}
+
static gboolean
read_pollable_cb (GPollableInputStream *istream,
gpointer user_data)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]