summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYossi Gottlieb <yossigo@gmail.com>2021-11-08 16:09:33 +0200
committerGitHub <noreply@github.com>2021-11-08 16:09:33 +0200
commita1aba4bf754fc6c650d37447b689ac4dea6baebf (patch)
treec8a0275327b1c59ae7b0a1d6bfe607e0cc06e249
parent48d870aed1a5c392f3c1b59db48bc15f9f43b963 (diff)
downloadredis-a1aba4bf754fc6c650d37447b689ac4dea6baebf.tar.gz
Fix EINTR test failures. (#9751)
* Clean up EINTR handling so EINTR will not change connection state to begin with. * On TLS, catch EINTR and return it as-is before going through OpenSSL error handling (which seems to not distinguish it from EAGAIN).
-rw-r--r--src/connection.c4
-rw-r--r--src/connection.h3
-rw-r--r--src/tls.c17
3 files changed, 18 insertions, 6 deletions
diff --git a/src/connection.c b/src/connection.c
index a59463220..3a17d983d 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -171,7 +171,7 @@ static int connSocketWrite(connection *conn, const void *data, size_t data_len)
/* Don't overwrite the state of a connection that is not already
* connected, not to mess with handler callbacks.
*/
- if (conn->state == CONN_STATE_CONNECTED)
+ if (errno != EINTR && conn->state == CONN_STATE_CONNECTED)
conn->state = CONN_STATE_ERROR;
}
@@ -188,7 +188,7 @@ static int connSocketRead(connection *conn, void *buf, size_t buf_len) {
/* Don't overwrite the state of a connection that is not already
* connected, not to mess with handler callbacks.
*/
- if (conn->state == CONN_STATE_CONNECTED)
+ if (errno != EINTR && conn->state == CONN_STATE_CONNECTED)
conn->state = CONN_STATE_ERROR;
}
diff --git a/src/connection.h b/src/connection.h
index f30a96367..07c1d4dd8 100644
--- a/src/connection.h
+++ b/src/connection.h
@@ -152,9 +152,6 @@ static inline int connWrite(connection *conn, const void *data, size_t data_len)
*/
static inline int connRead(connection *conn, void *buf, size_t buf_len) {
int ret = conn->type->read(conn, buf, buf_len);
- if (ret == -1 && conn->last_errno == EINTR) {
- conn->state = CONN_STATE_CONNECTED;
- }
return ret;
}
diff --git a/src/tls.c b/src/tls.c
index fb2a575ea..2a78b6562 100644
--- a/src/tls.c
+++ b/src/tls.c
@@ -750,7 +750,14 @@ static int connTLSWrite(connection *conn_, const void *data, size_t data_len) {
if (conn->c.state != CONN_STATE_CONNECTED) return -1;
ERR_clear_error();
ret = SSL_write(conn->ssl, data, data_len);
-
+ /* If system call was interrupted, there's no need to go through the full
+ * OpenSSL error handling and just report this for the caller to retry the
+ * operation.
+ */
+ if (errno == EINTR) {
+ conn->c.last_errno = EINTR;
+ return -1;
+ }
if (ret <= 0) {
WantIOType want = 0;
if (!(ssl_err = handleSSLReturnCode(conn, ret, &want))) {
@@ -781,6 +788,14 @@ static int connTLSRead(connection *conn_, void *buf, size_t buf_len) {
if (conn->c.state != CONN_STATE_CONNECTED) return -1;
ERR_clear_error();
ret = SSL_read(conn->ssl, buf, buf_len);
+ /* If system call was interrupted, there's no need to go through the full
+ * OpenSSL error handling and just report this for the caller to retry the
+ * operation.
+ */
+ if (errno == EINTR) {
+ conn->c.last_errno = EINTR;
+ return -1;
+ }
if (ret <= 0) {
WantIOType want = 0;
if (!(ssl_err = handleSSLReturnCode(conn, ret, &want))) {