]> granicus.if.org Git - neomutt/commitdiff
Add checks for buffered OpenSSL or GnuTLS data when polling
authorKevin McCarthy <kevin@8t8.us>
Sun, 28 Jul 2019 14:54:32 +0000 (07:54 -0700)
committerRichard Russon <rich@flatcap.org>
Mon, 19 Aug 2019 22:03:24 +0000 (23:03 +0100)
I don't believe this has had an actual effect, because NeoMutt doesn't
support renegotiation, and we are only polling immediately after
sending NOOP.

However, it looks like checking is technically the correct thing to do
to avoid polling waiting for data that is already buffered.

Co-authored-by: Richard Russon <rich@flatcap.org>
conn/ssl.c
conn/ssl_gnutls.c

index 4d293b7b5c43d409092b74d8147bf00f96edc6b0..1edf01dc052545f527d05a20cb213a7515ae7de8 100644 (file)
@@ -83,6 +83,7 @@ const int dialog_row_len = 128;
 #define X509_getm_notBefore X509_get_notBefore
 #define X509_getm_notAfter X509_get_notAfter
 #define X509_STORE_CTX_get0_chain X509_STORE_CTX_get_chain
+#define SSL_has_pending SSL_pending
 #endif
 
 /* This is ugly, but as RAND_status came in on OpenSSL version 0.9.5
@@ -645,6 +646,7 @@ static int ssl_socket_close_and_restore(struct Connection *conn)
   conn->conn_read = raw_socket_read;
   conn->conn_write = raw_socket_write;
   conn->conn_close = raw_socket_close;
+  conn->conn_poll = raw_socket_poll;
 
   return rc;
 }
@@ -1321,6 +1323,19 @@ free_sasldata:
   return -1;
 }
 
+/**
+ * ssl_socket_poll - Check whether a socket read would block - Implements Connection::conn_poll()
+ */
+static int ssl_socket_poll(struct Connection *conn, time_t wait_secs)
+{
+  struct SslSockData *data = conn->sockdata;
+
+  if (SSL_has_pending(data->ssl))
+    return 1;
+  else
+    return raw_socket_poll(conn, wait_secs);
+}
+
 /**
  * ssl_socket_open - Open an SSL socket - Implements Connection::conn_open()
  */
@@ -1420,6 +1435,7 @@ int mutt_ssl_starttls(struct Connection *conn)
   conn->conn_read = ssl_socket_read;
   conn->conn_write = ssl_socket_write;
   conn->conn_close = ssl_socket_close_and_restore;
+  conn->conn_poll = ssl_socket_poll;
 
   return rc;
 }
@@ -1441,7 +1457,7 @@ int mutt_ssl_socket_setup(struct Connection *conn)
   conn->conn_open = ssl_socket_open;
   conn->conn_read = ssl_socket_read;
   conn->conn_write = ssl_socket_write;
-  conn->conn_poll = raw_socket_poll;
+  conn->conn_poll = ssl_socket_poll;
   conn->conn_close = ssl_socket_close;
 
   return 0;
index e920342186c3ce34739bac461dded394be5375e6..f70cb9e15a194f0bf13c847b75e03c352614aaff 100644 (file)
@@ -111,6 +111,7 @@ static int tls_starttls_close(struct Connection *conn)
   conn->conn_read = raw_socket_read;
   conn->conn_write = raw_socket_write;
   conn->conn_close = raw_socket_close;
+  conn->conn_poll = raw_socket_poll;
 
   return rc;
 }
@@ -1114,6 +1115,19 @@ fail:
   return -1;
 }
 
+/**
+ * tls_socket_poll - Check whether a socket read would block - Implements Connection::conn_poll()
+ */
+static int tls_socket_poll(struct Connection *conn, time_t wait_secs)
+{
+  struct TlsSockData *data = conn->sockdata;
+
+  if (gnutls_record_check_pending(data->state))
+    return 1;
+  else
+    return raw_socket_poll(conn, wait_secs);
+}
+
 /**
  * tls_socket_open - Open a TLS socket - Implements Connection::conn_open()
  */
@@ -1232,7 +1246,7 @@ int mutt_ssl_socket_setup(struct Connection *conn)
   conn->conn_read = tls_socket_read;
   conn->conn_write = tls_socket_write;
   conn->conn_close = tls_socket_close;
-  conn->conn_poll = raw_socket_poll;
+  conn->conn_poll = tls_socket_poll;
 
   return 0;
 }
@@ -1254,6 +1268,7 @@ int mutt_ssl_starttls(struct Connection *conn)
   conn->conn_read = tls_socket_read;
   conn->conn_write = tls_socket_write;
   conn->conn_close = tls_starttls_close;
+  conn->conn_poll = tls_socket_poll;
 
   return 0;
 }