Unverified Commit a1aba4bf authored by Yossi Gottlieb's avatar Yossi Gottlieb Committed by GitHub
Browse files

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).
parent 48d870ae
...@@ -171,7 +171,7 @@ static int connSocketWrite(connection *conn, const void *data, size_t data_len) ...@@ -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 /* Don't overwrite the state of a connection that is not already
* connected, not to mess with handler callbacks. * 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; conn->state = CONN_STATE_ERROR;
} }
...@@ -188,7 +188,7 @@ static int connSocketRead(connection *conn, void *buf, size_t buf_len) { ...@@ -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 /* Don't overwrite the state of a connection that is not already
* connected, not to mess with handler callbacks. * 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; conn->state = CONN_STATE_ERROR;
} }
......
...@@ -152,9 +152,6 @@ static inline int connWrite(connection *conn, const void *data, size_t data_len) ...@@ -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) { static inline int connRead(connection *conn, void *buf, size_t buf_len) {
int ret = conn->type->read(conn, buf, 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; return ret;
} }
......
...@@ -750,7 +750,14 @@ static int connTLSWrite(connection *conn_, const void *data, size_t data_len) { ...@@ -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; if (conn->c.state != CONN_STATE_CONNECTED) return -1;
ERR_clear_error(); ERR_clear_error();
ret = SSL_write(conn->ssl, data, data_len); 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) { if (ret <= 0) {
WantIOType want = 0; WantIOType want = 0;
if (!(ssl_err = handleSSLReturnCode(conn, ret, &want))) { if (!(ssl_err = handleSSLReturnCode(conn, ret, &want))) {
...@@ -781,6 +788,14 @@ static int connTLSRead(connection *conn_, void *buf, size_t buf_len) { ...@@ -781,6 +788,14 @@ static int connTLSRead(connection *conn_, void *buf, size_t buf_len) {
if (conn->c.state != CONN_STATE_CONNECTED) return -1; if (conn->c.state != CONN_STATE_CONNECTED) return -1;
ERR_clear_error(); ERR_clear_error();
ret = SSL_read(conn->ssl, buf, buf_len); 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) { if (ret <= 0) {
WantIOType want = 0; WantIOType want = 0;
if (!(ssl_err = handleSSLReturnCode(conn, ret, &want))) { if (!(ssl_err = handleSSLReturnCode(conn, ret, &want))) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment