[glib-networking/mcatanzaro/#20: 16/18] gnutls: account for internal TLS buffer in check function
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking/mcatanzaro/#20: 16/18] gnutls: account for internal TLS buffer in check function
- Date: Tue, 1 Sep 2020 18:24:32 +0000 (UTC)
commit 4dbb780f40f5b1dfb0159acb697b48e2e4acce26
Author: Michael Catanzaro <mcatanzaro gnome org>
Date: Sun Jan 26 14:33:09 2020 -0600
gnutls: account for internal TLS buffer in check function
If the GnuTLS buffer has readable data, then we must report that we are
readable, or applications could stall forever waiting to read the data
that is already present.
Fixes #20
tls/base/gtlsconnection-base.c | 10 ++++++++++
tls/base/gtlsconnection-base.h | 3 +++
tls/gnutls/gtlsconnection-gnutls.c | 14 ++++++++++++++
3 files changed, 27 insertions(+)
---
diff --git a/tls/base/gtlsconnection-base.c b/tls/base/gtlsconnection-base.c
index 5d8ab2b4..e184552d 100644
--- a/tls/base/gtlsconnection-base.c
+++ b/tls/base/gtlsconnection-base.c
@@ -921,6 +921,16 @@ g_tls_connection_base_check (GTlsConnectionBase *tls,
((condition & G_IO_OUT) && (priv->writing || priv->write_closing)))
goto out;
+ /* If base class says we are ready, then we are, regardless of the base
+ * stream status. This accounts for TLS-level buffers.
+ */
+ if (G_TLS_CONNECTION_BASE_GET_CLASS (tls)->check &&
+ G_TLS_CONNECTION_BASE_GET_CLASS (tls)->check (tls, condition))
+ {
+ ret = TRUE;
+ goto out;
+ }
+
/* Defer to the base stream or GDatagramBased. */
ret = g_tls_connection_base_base_check (tls, condition);
diff --git a/tls/base/gtlsconnection-base.h b/tls/base/gtlsconnection-base.h
index 45c14e52..86425023 100644
--- a/tls/base/gtlsconnection-base.h
+++ b/tls/base/gtlsconnection-base.h
@@ -79,6 +79,9 @@ struct _GTlsConnectionBaseClass
gboolean (*is_session_resumed) (GTlsConnectionBase *tls);
+ gboolean (*check) (GTlsConnectionBase *tls,
+ GIOCondition direction);
+
void (*push_io) (GTlsConnectionBase *tls,
GIOCondition direction,
gint64 timeout,
diff --git a/tls/gnutls/gtlsconnection-gnutls.c b/tls/gnutls/gtlsconnection-gnutls.c
index 1e099574..3aab9e43 100644
--- a/tls/gnutls/gtlsconnection-gnutls.c
+++ b/tls/gnutls/gtlsconnection-gnutls.c
@@ -848,6 +848,19 @@ g_tls_connection_gnutls_is_session_resumed (GTlsConnectionBase *tls)
return gnutls_session_is_resumed (priv->session);
}
+static gboolean
+g_tls_connection_gnutls_check (GTlsConnectionBase *tls,
+ GIOCondition direction)
+{
+ GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (tls);
+ GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
+
+ if (direction & G_IO_IN)
+ return !!gnutls_record_check_pending (priv->session);
+
+ return FALSE;
+}
+
static GTlsConnectionBaseStatus
g_tls_connection_gnutls_read (GTlsConnectionBase *tls,
void *buffer,
@@ -1071,6 +1084,7 @@ 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->check = g_tls_connection_gnutls_check;
base_class->read_fn = g_tls_connection_gnutls_read;
base_class->read_message_fn = g_tls_connection_gnutls_read_message;
base_class->write_fn = g_tls_connection_gnutls_write;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]