diff --git a/src/tls_gnutls.c b/src/tls_gnutls.c index 0aa7c284..ab9f2f1c 100644 --- a/src/tls_gnutls.c +++ b/src/tls_gnutls.c @@ -14,7 +14,9 @@ * TLS implementation with GNUTLS */ +#include #include +#include #include #include #include @@ -665,6 +667,15 @@ int tls_read(struct conn_interface *intf, void *buff, size_t len) ret = gnutls_record_recv(tls->session, buff, len); tls->lasterror = ret < 0 ? ret : 0; + if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED) { + char c; + ssize_t n = recv(intf->conn->sock, &c, 1, MSG_PEEK); + if (n < 0 && errno == ENOTCONN) { + strophe_debug(tls->ctx, "tls", "EAGAIN but connection is closed"); + tls->lasterror = GNUTLS_E_PULL_ERROR; + } + } + return ret; } diff --git a/src/tls_openssl.c b/src/tls_openssl.c index 67d2c8a8..2b536932 100644 --- a/src/tls_openssl.c +++ b/src/tls_openssl.c @@ -19,6 +19,7 @@ #ifndef _WIN32 #include +#include #else #include #endif @@ -963,6 +964,19 @@ int tls_read(struct conn_interface *intf, void *buff, size_t len) ret = SSL_read(tls->ssl, buff, len); _tls_set_error(tls, ret <= 0 ? SSL_get_error(tls->ssl, ret) : 0); +#ifndef _WIN32 + if (tls->lasterror == SSL_ERROR_WANT_READ) { + char c; + ssize_t n = recv(intf->conn->sock, &c, 1, MSG_PEEK); + if (n < 0 && errno == ENOTCONN) { + strophe_debug(tls->ctx, "tls", + "WANT_READ but connection is closed"); + _tls_set_error(tls, + SSL_ERROR_SYSCALL); // Set a more appropriate error + } + } +#endif + return ret; }