You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2019/10/12 17:16:34 UTC

[httpcomponents-core] 01/02: HTTPCORE-601: work-around for SSL session spin on outbound session closure with Conscrypt 2.2.1 (back-ported from master)

This is an automated email from the ASF dual-hosted git repository.

olegk pushed a commit to branch jsse-provider-tests-4.4
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git

commit 29cae46595f77a290a34c870a8620d2dfa2005fb
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Sat Oct 12 19:13:38 2019 +0200

    HTTPCORE-601: work-around for SSL session spin on outbound session closure with Conscrypt 2.2.1 (back-ported from master)
---
 .../java/org/apache/http/nio/reactor/ssl/SSLIOSession.java | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLIOSession.java b/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLIOSession.java
index 96447d7..71b3738 100644
--- a/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLIOSession.java
+++ b/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLIOSession.java
@@ -35,6 +35,7 @@ import java.nio.channels.ByteChannel;
 import java.nio.channels.CancelledKeyException;
 import java.nio.channels.ClosedChannelException;
 import java.nio.channels.SelectionKey;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLEngine;
@@ -89,6 +90,7 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
     private final SSLBuffer inPlain;
     private final InternalByteChannel channel;
     private final SSLSetupHandler handler;
+    private final AtomicInteger outboundClosedCount;
 
     private int appEventMask;
     private SessionBufferStatus appBufferStatus;
@@ -163,6 +165,7 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
         // Allocate buffers for application (unencrypted) data
         final int appBuffersize = this.sslEngine.getSession().getApplicationBufferSize();
         this.inPlain = bufferManagementStrategy.constructBuffer(appBuffersize);
+        this.outboundClosedCount = new AtomicInteger(0);
     }
 
     /**
@@ -294,7 +297,15 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
 
         SSLEngineResult result = null;
         while (handshaking) {
-            switch (this.sslEngine.getHandshakeStatus()) {
+            HandshakeStatus handshakeStatus = this.sslEngine.getHandshakeStatus();
+
+            // Work-around for what appears to be a bug in Conscrypt SSLEngine that does not
+            // transition into the handshaking state upon #closeOutbound() call but still
+            // has some handshake data stuck in its internal buffer.
+            if (handshakeStatus == HandshakeStatus.NOT_HANDSHAKING && outboundClosedCount.get() > 0) {
+                handshakeStatus = HandshakeStatus.NEED_WRAP;
+            }
+            switch (handshakeStatus) {
             case NEED_WRAP:
                // Generate outgoing handshake data
 
@@ -370,6 +381,7 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
         }
         if (this.status == CLOSING && !this.outEncrypted.hasData()) {
             this.sslEngine.closeOutbound();
+            this.outboundClosedCount.incrementAndGet();
         }
         if (this.status == CLOSING && this.sslEngine.isOutboundDone()
                 && (this.endOfStream || this.sslEngine.isInboundDone())