Author: remm
Date: Tue Feb  2 17:46:17 2016
New Revision: 1728162

URL: http://svn.apache.org/viewvc?rev=1728162&view=rev
Log:
Port Mark's patch to NIO2 in places where it can be useful, also add a separate 
log message for the resize failure.

Modified:
    tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties
    tomcat/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java
    tomcat/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java
    tomcat/trunk/webapps/docs/changelog.xml

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties?rev=1728162&r1=1728161&r2=1728162&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties Tue 
Feb  2 17:46:17 2016
@@ -97,6 +97,7 @@ channel.nio.ssl.remainingDataDuringClose
 channel.nio.ssl.pendingWriteDuringClose=Pending write, so remaining data in 
the network buffer, can't send SSL close message, force a close with 
close(true) instead
 channel.nio.ssl.invalidCloseState=Invalid close state, will not send network 
data.
 channel.nio.ssl.unwrapFail=Unable to unwrap data, invalid status [{0}]
+channel.nio.ssl.unwrapFailResize=Unable to unwrap data because buffer is too 
small, invalid status [{0}]
 channel.nio.ssl.wrapException=Handshake failed during wrap
 channel.nio.ssl.wrapFail=Unable to wrap data, invalid status [{0}]
 channel.nio.ssl.incompleteHandshake=Handshake incomplete, you must complete 
handshake before reading data.

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java?rev=1728162&r1=1728161&r2=1728162&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java Tue Feb 
 2 17:46:17 2016
@@ -573,7 +573,7 @@ public class SecureNio2Channel extends N
     }
 
     private class FutureRead implements Future<Integer> {
-        private final ByteBuffer dst;
+        private ByteBuffer dst;
         private Future<Integer> integer;
         private FutureRead(ByteBuffer dst) {
             this.dst = dst;
@@ -652,17 +652,31 @@ public class SecureNio2Channel extends N
                             break;
                         }
                     }
-                } else if (unwrap.getStatus() == Status.BUFFER_OVERFLOW && 
read > 0) {
-                    //buffer overflow can happen, if we have read data, then
-                    //empty out the dst buffer before we do another read
-                    break;
+                } else if (unwrap.getStatus() == Status.BUFFER_OVERFLOW) {
+                    if (read > 0) {
+                        // Buffer overflow can happen if we have read data. 
Return
+                        // so the destination buffer can be emptied before 
another
+                        // read is attempted
+                        break;
+                    } else {
+                        // The SSL session has increased the required buffer 
size
+                        // since the buffer was created.
+                        if (dst == 
socket.getSocketBufferHandler().getReadBuffer()) {
+                            // This is the normal case for this code
+                            socket.getSocketBufferHandler().expand(
+                                    
sslEngine.getSession().getApplicationBufferSize());
+                            dst = 
socket.getSocketBufferHandler().getReadBuffer();
+                        } else {
+                            // Can't expand the buffer as there is no way to 
signal
+                            // to the caller that the buffer has been replaced.
+                            throw new ExecutionException(new 
IOException(sm.getString("channel.nio.ssl.unwrapFailResize", 
unwrap.getStatus())));
+                        }
+                    }
                 } else {
-                    //here we should trap BUFFER_OVERFLOW and call expand on 
the buffer
-                    //for now, throw an exception, as we initialized the 
buffers
-                    //in the constructor
+                    // Something else went wrong
                     throw new ExecutionException(new 
IOException(sm.getString("channel.nio.ssl.unwrapFail", unwrap.getStatus())));
                 }
-            } while ((netInBuffer.position() != 0)); //continue to unwrapping 
as long as the input buffer has stuff
+            } while (netInBuffer.position() != 0); //continue to unwrapping as 
long as the input buffer has stuff
             if (!dst.hasRemaining()) {
                 unwrapBeforeRead = true;
             } else {
@@ -796,6 +810,7 @@ public class SecureNio2Channel extends N
                     failed(new EOFException(), attach);
                 } else {
                     try {
+                        ByteBuffer dst2 = dst;
                         //the data read
                         int read = 0;
                         //the SSL engine result
@@ -804,7 +819,7 @@ public class SecureNio2Channel extends N
                             //prepare the buffer
                             netInBuffer.flip();
                             //unwrap the data
-                            unwrap = sslEngine.unwrap(netInBuffer, dst);
+                            unwrap = sslEngine.unwrap(netInBuffer, dst2);
                             //compact the buffer
                             netInBuffer.compact();
                             if (unwrap.getStatus() == Status.OK || 
unwrap.getStatus() == Status.BUFFER_UNDERFLOW) {
@@ -822,19 +837,34 @@ public class SecureNio2Channel extends N
                                         break;
                                     }
                                 }
-                            } else if (unwrap.getStatus() == 
Status.BUFFER_OVERFLOW && read > 0) {
-                                //buffer overflow can happen, if we have read 
data, then
-                                //empty out the dst buffer before we do 
another read
-                                break;
+                            } else if (unwrap.getStatus() == 
Status.BUFFER_OVERFLOW) {
+                                if (read > 0) {
+                                    // Buffer overflow can happen if we have 
read data. Return
+                                    // so the destination buffer can be 
emptied before another
+                                    // read is attempted
+                                    break;
+                                } else {
+                                    // The SSL session has increased the 
required buffer size
+                                    // since the buffer was created.
+                                    if (dst2 == 
socket.getSocketBufferHandler().getReadBuffer()) {
+                                        // This is the normal case for this 
code
+                                        socket.getSocketBufferHandler().expand(
+                                                
sslEngine.getSession().getApplicationBufferSize());
+                                        dst2 = 
socket.getSocketBufferHandler().getReadBuffer();
+                                    } else {
+                                        // Can't expand the buffer as there is 
no way to signal
+                                        // to the caller that the buffer has 
been replaced.
+                                        throw new IOException(
+                                                
sm.getString("channel.nio.ssl.unwrapFailResize", unwrap.getStatus()));
+                                    }
+                                }
                             } else {
-                                //here we should trap BUFFER_OVERFLOW and call 
expand on the buffer
-                                //for now, throw an exception, as we 
initialized the buffers
-                                //in the constructor
+                                // Something else went wrong
                                 throw new 
IOException(sm.getString("channel.nio.ssl.unwrapFail", unwrap.getStatus()));
                             }
                         // continue to unwrap as long as the input buffer has 
stuff
                         } while (netInBuffer.position() != 0);
-                        if (!dst.hasRemaining()) {
+                        if (!dst2.hasRemaining()) {
                             unwrapBeforeRead = true;
                         } else {
                             unwrapBeforeRead = false;
@@ -915,7 +945,7 @@ public class SecureNio2Channel extends N
                                 //in the constructor
                                 throw new 
IOException(sm.getString("channel.nio.ssl.unwrapFail", unwrap.getStatus()));
                             }
-                        } while ((netInBuffer.position() != 0)); //continue to 
unwrapping as long as the input buffer has stuff
+                        } while (netInBuffer.position() != 0); //continue to 
unwrapping as long as the input buffer has stuff
                         int capacity = 0;
                         final int endOffset = offset + length;
                         for (int i = offset; i < endOffset; i++) {

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java?rev=1728162&r1=1728161&r2=1728162&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java Tue Feb  
2 17:46:17 2016
@@ -576,7 +576,7 @@ public class SecureNioChannel extends Ni
                         // Can't expand the buffer as there is no way to signal
                         // to the caller that the buffer has been replaced.
                         throw new IOException(
-                                sm.getString("channel.nio.ssl.unwrapFail", 
unwrap.getStatus()));
+                                
sm.getString("channel.nio.ssl.unwrapFailResize", unwrap.getStatus()));
                     }
                 }
             } else {

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1728162&r1=1728161&r2=1728162&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Tue Feb  2 17:46:17 2016
@@ -45,6 +45,14 @@
   issues do not "pop up" wrt. others).
 -->
 <section name="Tomcat 9.0.0.M4" rtext="In development">
+  <subsection name="Coyote">
+    <changelog>
+      <fix>
+        Handle the case in the NIO2 connector where the required TLS buffer
+        sizes increase after the connection has been initiated. (markt/remm)
+      </fix>
+    </changelog>
+  </subsection>
   <subsection name="WebSocket">
     <changelog>
       <fix>



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to