diff options
author | Andreas Metzler <ametzler@bebt.de> | 2018-12-24 16:11:41 +0000 |
---|---|---|
committer | Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de> | 2018-12-25 22:43:45 +0100 |
commit | 4896a3192ffac48885347460377edcd893eb9600 (patch) | |
tree | b362c355a6f9e98cc1b773c6373282fce163aac3 | |
parent | b315e9a9f95471046f568ce4841b3b66746adcac (diff) |
GnuTLS: repeat lowlevel read and write operations while they request retry
(cherry picked from commit 06faf21f3a84a3ac4aa4f7b1512087423d8c8541)
-rw-r--r-- | doc/doc-txt/ChangeLog | 7 | ||||
-rw-r--r-- | src/src/tls-gnu.c | 28 |
2 files changed, 26 insertions, 9 deletions
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 785d59bed..ec7c8accd 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -5,6 +5,13 @@ affect Exim's operation, with an unchanged configuration file. For new options, and new features, see the NewStuff file next to this ChangeLog. +Exim version 4.93 +----------------- + +JH/01 GnuTLS: repeat lowlevel read and write operations while they return error + codes indicating retry. Under TLS1.3 this becomes required. + + Exim version 4.92 ----------------- diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index bceb57395..c404dc29a 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -2562,8 +2562,12 @@ DEBUG(D_tls) debug_printf("Calling gnutls_record_recv(%p, %p, %u)\n", sigalrm_seen = FALSE; if (smtp_receive_timeout > 0) ALARM(smtp_receive_timeout); -inbytes = gnutls_record_recv(state->session, state->xfer_buffer, - MIN(ssl_xfer_buffer_size, lim)); + +do + inbytes = gnutls_record_recv(state->session, state->xfer_buffer, + MIN(ssl_xfer_buffer_size, lim)); +while (inbytes == GNUTLS_E_AGAIN); + if (smtp_receive_timeout > 0) ALARM_CLR(0); if (had_command_timeout) /* set by signal handler */ @@ -2618,7 +2622,7 @@ else if (inbytes == 0) else if (inbytes < 0) { -debug_printf("%s: err from gnutls_record_recv(\n", __FUNCTION__); + DEBUG(D_tls) debug_printf("%s: err from gnutls_record_recv(\n", __FUNCTION__); record_io_error(state, (int) inbytes, US"recv", NULL); state->xfer_error = TRUE; return FALSE; @@ -2740,17 +2744,20 @@ DEBUG(D_tls) debug_printf("Calling gnutls_record_recv(%p, %p, " SIZE_T_FMT ")\n", state->session, buff, len); -inbytes = gnutls_record_recv(state->session, buff, len); +do + inbytes = gnutls_record_recv(state->session, buff, len); +while (inbytes == GNUTLS_E_AGAIN); + if (inbytes > 0) return inbytes; if (inbytes == 0) { DEBUG(D_tls) debug_printf("Got TLS_EOF\n"); } else -{ -debug_printf("%s: err from gnutls_record_recv(\n", __FUNCTION__); -record_io_error(state, (int)inbytes, US"recv", NULL); -} + { + DEBUG(D_tls) debug_printf("%s: err from gnutls_record_recv(\n", __FUNCTION__); + record_io_error(state, (int)inbytes, US"recv", NULL); + } return -1; } @@ -2792,7 +2799,10 @@ while (left > 0) { DEBUG(D_tls) debug_printf("gnutls_record_send(SSL, %p, " SIZE_T_FMT ")\n", buff, left); - outbytes = gnutls_record_send(state->session, buff, left); + + do + outbytes = gnutls_record_send(state->session, buff, left); + while (outbytes == GNUTLS_E_AGAIN); DEBUG(D_tls) debug_printf("outbytes=" SSIZE_T_FMT "\n", outbytes); if (outbytes < 0) |