]> granicus.if.org Git - apache/commitdiff
Fix hung SSL handshake if a particularly long CA list is configured:
authorJoe Orton <jorton@apache.org>
Fri, 26 Jun 2009 14:22:20 +0000 (14:22 +0000)
committerJoe Orton <jorton@apache.org>
Fri, 26 Jun 2009 14:22:20 +0000 (14:22 +0000)
* modules/ssl/ssl_engine_io.c (bio_filter_in_read): Flush pending
  output unconditionally since OpenSSL is known to not flush correctly
  at all times, and it should be cheap even in cases where it is
  unnecessary.

PR: 46952

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@788715 13f79535-47bb-0310-9956-ffa450edef68

modules/ssl/ssl_engine_io.c

index 622083bc61c94c5294ea4e2fbb894ead24f4069f..ae9d36af9856b0a3c93056a99a16a2eedbdbe3fe 100644 (file)
@@ -469,7 +469,6 @@ static int bio_filter_in_read(BIO *bio, char *in, int inlen)
     apr_size_t inl = inlen;
     bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)(bio->ptr);
     apr_read_type_e block = inctx->block;
-    SSLConnRec *sslconn = myConnConfig(inctx->f->c);
 
     inctx->rc = APR_SUCCESS;
 
@@ -477,17 +476,19 @@ static int bio_filter_in_read(BIO *bio, char *in, int inlen)
     if (!in)
         return 0;
 
-    /* XXX: flush here only required for SSLv2;
-     * OpenSSL calls BIO_flush() at the appropriate times for
-     * the other protocols.
+    /* In theory, OpenSSL should flush as necessary, but it is known
+     * not to do so correctly in some cases; see PR 46952.
+     *
+     * Historically, this flush call was performed only for an SSLv2
+     * connection or for a proxy connection.  Calling _out_flush
+     * should be very cheap in cases where it is unnecessary (and no
+     * output is buffered) so the performance impact of doing it
+     * unconditionally should be minimal.
      */
-    if ((SSL_version(inctx->ssl) == SSL2_VERSION) || sslconn->is_proxy) {
-        if (bio_filter_out_flush(inctx->bio_out) < 0) {
-            bio_filter_out_ctx_t *outctx =
-                   (bio_filter_out_ctx_t *)(inctx->bio_out->ptr);
-            inctx->rc = outctx->rc;
-            return -1;
-        }
+    if (bio_filter_out_flush(inctx->bio_out) < 0) {
+        bio_filter_out_ctx_t *outctx = inctx->bio_out->ptr;
+        inctx->rc = outctx->rc;
+        return -1;
     }
 
     BIO_clear_retry_flags(bio);