[glib-networking/wip/pwithnall/dtls: 1/12] gnutls: Add support for timeouts on GnuTLS pulls
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking/wip/pwithnall/dtls: 1/12] gnutls: Add support for timeouts on GnuTLS pulls
- Date: Mon, 18 Jan 2016 18:08:48 +0000 (UTC)
commit 2ad63213f1a7d742dd81a4ad7a9731aac64bb957
Author: Olivier CrĂȘte <olivier crete collabora com>
Date: Fri Jul 3 12:43:45 2015 +0100
gnutls: Add support for timeouts on GnuTLS pulls
Set a gnutls_pull_timeout_func for GnuTLS to use. This is necessary for
supporting timeouts and for DTLS.
https://bugzilla.gnome.org/show_bug.cgi?id=697908
tls/gnutls/gtlsconnection-gnutls.c | 62 ++++++++++++++++++++++++++++++++++++
1 files changed, 62 insertions(+), 0 deletions(-)
---
diff --git a/tls/gnutls/gtlsconnection-gnutls.c b/tls/gnutls/gtlsconnection-gnutls.c
index ca4730b..c8a6a07 100644
--- a/tls/gnutls/gtlsconnection-gnutls.c
+++ b/tls/gnutls/gtlsconnection-gnutls.c
@@ -59,6 +59,10 @@ static ssize_t g_tls_connection_gnutls_pull_func (gnutls_transport_ptr_t transp
void *buf,
size_t buflen);
+static int g_tls_connection_gnutls_pull_timeout_func (gnutls_transport_ptr_t transport_data,
+ unsigned int ms);
+
+
static void g_tls_connection_gnutls_initable_iface_init (GInitableIface *iface);
static gboolean g_tls_connection_gnutls_initable_init (GInitable *initable,
GCancellable *cancellable,
@@ -329,6 +333,8 @@ g_tls_connection_gnutls_initable_init (GInitable *initable,
g_tls_connection_gnutls_push_func);
gnutls_transport_set_pull_function (gnutls->priv->session,
g_tls_connection_gnutls_pull_func);
+ gnutls_transport_set_pull_timeout_function (gnutls->priv->session,
+ g_tls_connection_gnutls_pull_timeout_func);
gnutls_transport_set_ptr (gnutls->priv->session, gnutls);
gnutls->priv->tls_istream = g_tls_input_stream_gnutls_new (gnutls);
@@ -1151,6 +1157,62 @@ g_tls_connection_gnutls_push_func (gnutls_transport_ptr_t transport_data,
return ret;
}
+static gboolean
+read_cb (GPollableInputStream *istream, gpointer user_data)
+{
+ gboolean *read_done = user_data;
+
+ *read_done = TRUE;
+
+ return G_SOURCE_CONTINUE;
+}
+
+static int
+g_tls_connection_gnutls_pull_timeout_func (gnutls_transport_ptr_t transport_data,
+ unsigned int ms)
+{
+ GTlsConnectionGnutls *gnutls = transport_data;
+ GMainContext *ctx = NULL;
+ GSource *read_source;
+ gboolean read_done = FALSE;
+ GPollableInputStream *pollable_stream;
+
+ pollable_stream = G_POLLABLE_INPUT_STREAM (gnutls->priv->base_istream);
+
+ /* Fast path. */
+ if (g_pollable_input_stream_is_readable (pollable_stream) ||
+ g_cancellable_is_cancelled (gnutls->priv->read_cancellable))
+ return 1;
+ else if (ms == 0)
+ return 0;
+
+ /* Slow path: wait for readability. */
+ ctx = g_main_context_new ();
+
+ read_source = g_pollable_input_stream_create_source (pollable_stream,
+ gnutls->priv->read_cancellable);
+ g_source_set_ready_time (read_source, g_get_monotonic_time () + ms * 1000);
+ g_source_set_callback (read_source, (GSourceFunc) read_cb,
+ &read_done, NULL);
+ g_source_attach (read_source, ctx);
+
+ while (!read_done)
+ g_main_context_iteration (ctx, TRUE);
+
+ g_source_destroy (read_source);
+
+ g_main_context_unref (ctx);
+ g_source_unref (read_source);
+
+ /* If @read_source was dispatched due to cancellation, the resulting error
+ * will be handled in g_tls_connection_gnutls_pull_func(). */
+ if (g_pollable_input_stream_is_readable (pollable_stream) ||
+ g_cancellable_is_cancelled (gnutls->priv->read_cancellable))
+ return 1;
+
+ return 0;
+}
+
static GTlsCertificate *
get_peer_certificate_from_session (GTlsConnectionGnutls *gnutls)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]