You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2016/02/02 18:46:18 UTC

svn commit: r1728162 - in /tomcat/trunk: java/org/apache/tomcat/util/net/LocalStrings.properties java/org/apache/tomcat/util/net/SecureNio2Channel.java java/org/apache/tomcat/util/net/SecureNioChannel.java webapps/docs/changelog.xml

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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org