[exim-cvs] GnuTLS: fix hanging callout connections

Αρχική Σελίδα
Delete this message
Reply to this message
Συντάκτης: Exim Git Commits Mailing List
Ημερομηνία:  
Προς: exim-cvs
Αντικείμενο: [exim-cvs] GnuTLS: fix hanging callout connections
Gitweb: https://git.exim.org/exim.git/commitdiff/bd95ffc2ba87fbd3c752df17bc8fd9c01586d45a
Commit:     bd95ffc2ba87fbd3c752df17bc8fd9c01586d45a
Parent:     5c329a4388e7113925109e093e8cbb12ddf6fa8b
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Thu Feb 13 16:45:38 2020 +0000
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Thu Feb 13 16:46:36 2020 +0000


    GnuTLS: fix hanging callout connections


    Broken-by: 925ac8e4f1
---
 doc/doc-txt/ChangeLog |  5 +++++
 src/src/tls-gnu.c     | 24 ++++++++++++++----------
 2 files changed, 19 insertions(+), 10 deletions(-)


diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index a5367f9..22ea6ad 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -121,6 +121,11 @@ JH/24 Bug 2524: fix the cyrus_sasl auth driver gssapi usage.  A previous fix
       block of data.  Investigation showed the copy to actually be needless, the
       data being length-specified.


+JH/25 Fix use of concurrent TLS connections under GnuTLS.  When a callout was
+      done during a receiving connection, and both used TLS, global info was
+      used rather than per-connection info for tracking the state of data
+      queued for transmission.  This could result in a connection hang.
+


 Exim version 4.93
 -----------------
diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c
index 0e13f2c..2e69c59 100644
--- a/src/src/tls-gnu.c
+++ b/src/src/tls-gnu.c
@@ -177,10 +177,17 @@ typedef struct exim_gnutls_state {
   enum peer_verify_requirement verify_requirement;
   int            fd_in;
   int            fd_out;
-  BOOL            peer_cert_verified;
-  BOOL            peer_dane_verified;
-  BOOL            trigger_sni_changes;
-  BOOL            have_set_peerdn;
+
+  BOOL            peer_cert_verified:1;
+  BOOL            peer_dane_verified:1;
+  BOOL            trigger_sni_changes:1;
+  BOOL            have_set_peerdn:1;
+  BOOL            xfer_eof:1;    /*XXX never gets set! */
+  BOOL            xfer_error:1;
+#ifdef SUPPORT_CORK
+  BOOL            corked:1;
+#endif
+
   const struct host_item *host;        /* NULL if server */
   gnutls_x509_crt_t    peercert;
   uschar        *peerdn;
@@ -213,8 +220,6 @@ typedef struct exim_gnutls_state {
   uschar *xfer_buffer;
   int xfer_buffer_lwm;
   int xfer_buffer_hwm;
-  BOOL xfer_eof;    /*XXX never gets set! */
-  BOOL xfer_error;
 } exim_gnutls_state_st;


static const exim_gnutls_state_st exim_gnutls_state_init = {
@@ -3348,9 +3353,8 @@ ssize_t outbytes;
size_t left = len;
exim_gnutls_state_st * state = ct_ctx ? ct_ctx : &state_server;
#ifdef SUPPORT_CORK
-static BOOL corked = FALSE;

-if (more && !corked) gnutls_record_cork(state->session);
+if (more && !state->corked) gnutls_record_cork(state->session);
#endif

DEBUG(D_tls) debug_printf("%s(%p, " SIZE_T_FMT "%s)\n", __FUNCTION__,
@@ -3391,10 +3395,10 @@ if (len > INT_MAX)
}

#ifdef SUPPORT_CORK
-if (more != corked)
+if (more != state->corked)
{
if (!more) (void) gnutls_record_uncork(state->session, 0);
- corked = more;
+ state->corked = more;
}
#endif