From: Kevin McCarthy Date: Sun, 28 Jul 2019 14:54:32 +0000 (-0700) Subject: Add checks for buffered OpenSSL or GnuTLS data when polling X-Git-Tag: 2019-10-25~98^2~4 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c9131a3e78d440c899a1ef93742566b92ba5863e;p=neomutt Add checks for buffered OpenSSL or GnuTLS data when polling 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 --- diff --git a/conn/ssl.c b/conn/ssl.c index 4d293b7b5..1edf01dc0 100644 --- a/conn/ssl.c +++ b/conn/ssl.c @@ -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; diff --git a/conn/ssl_gnutls.c b/conn/ssl_gnutls.c index e92034218..f70cb9e15 100644 --- a/conn/ssl_gnutls.c +++ b/conn/ssl_gnutls.c @@ -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; }