You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2015/04/09 23:15:11 UTC
svn commit: r1672492 - in /tomcat/trunk/java/org/apache/tomcat/util/net:
LocalStrings.properties SNIExtractor.java SecureNioChannel.java
Author: markt
Date: Thu Apr 9 21:15:11 2015
New Revision: 1672492
URL: http://svn.apache.org/r1672492
Log:
SNI refactoring for NIO.
Peek at the data but currently parsing the data is stubbed to report no hostname found.
Added:
tomcat/trunk/java/org/apache/tomcat/util/net/SNIExtractor.java (with props)
Modified:
tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties
tomcat/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java
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=1672492&r1=1672491&r2=1672492&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties Thu Apr 9 21:15:11 2015
@@ -94,6 +94,8 @@ channel.nio.ssl.wrapFail=Unable to wrap
channel.nio.ssl.incompleteHandshake=Handshake incomplete, you must complete handshake before reading data.
channel.nio.ssl.closing=Channel is in closing state.
channel.nio.ssl.invalidBuffer=You can only read using the application read buffer provided by the handler.
+channel.nio.ssl.expandNetInBuffer=Expanding network input buffer to [{0}] bytes
+channel.nio.ssl.expandNetOutBuffer=Expanding network input buffer to [{0}] bytes
socket.closed=The socket associated with this connection has been closed.
Added: tomcat/trunk/java/org/apache/tomcat/util/net/SNIExtractor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SNIExtractor.java?rev=1672492&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SNIExtractor.java (added)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SNIExtractor.java Thu Apr 9 21:15:11 2015
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.util.net;
+
+import java.nio.ByteBuffer;
+
+public class SNIExtractor {
+
+ private final SNIResult result = SNIResult.NOT_PRESENT;
+ private final String sniValue = null;
+
+ public SNIExtractor(ByteBuffer netInBuffer) {
+ // TODO: Detect use of http on a secure connection and provide a simple
+ // error page.
+
+ int pos = netInBuffer.position();
+ try {
+ // TODO Parse the data
+
+ } finally {
+ // Whatever happens, return the buffer to its original state
+ netInBuffer.limit(netInBuffer.capacity());
+ netInBuffer.position(pos);
+ }
+ }
+
+ public SNIResult getResult() {
+ return result;
+ }
+
+ public String getSNIValue() {
+ if (result == SNIResult.FOUND) {
+ return sniValue;
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public static enum SNIResult {
+ FOUND,
+ NOT_PRESENT,
+ UNDERFLOW,
+ ERROR
+ }
+}
Propchange: tomcat/trunk/java/org/apache/tomcat/util/net/SNIExtractor.java
------------------------------------------------------------------------------
svn:eol-style = native
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=1672492&r1=1672491&r2=1672492&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java Thu Apr 9 21:15:11 2015
@@ -28,16 +28,23 @@ import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
import javax.net.ssl.SSLEngineResult.Status;
-import javax.net.ssl.SSLException;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.util.res.StringManager;
/**
- *
* Implementation of a secure socket channel
- * @version 1.0
*/
-
public class SecureNioChannel extends NioChannel {
+ private static final Log log = LogFactory.getLog(SecureNioChannel.class);
+ private static final StringManager sm = StringManager.getManager(SecureNioChannel.class);
+
+ // Value determined by observation of what the SSL Engine requested in
+ // various scenarios
+ private static final int DEFAULT_NET_BUFFER_SIZE = 16921;
+
protected ByteBuffer netInBuffer;
protected ByteBuffer netOutBuffer;
@@ -211,50 +218,50 @@ public class SecureNioChannel extends Ni
* present and, if it is, what host name has been requested. Based on the
* provided host name, configure the SSLEngine for this connection.
*/
- private int processSNI() throws SSLException {
- // TODO The peek at the available data to determine the host requested
- // via SNI (if any) goes here.
-
+ private int processSNI() throws IOException {
SocketProperties sp = endpoint.getSocketProperties();
- sslEngine = endpoint.createSSLEngine();
-
- // Ensure the application buffers (which have to be created earlier) are
- // big enough.
- bufHandler.expand(sslEngine.getSession().getApplicationBufferSize());
- // Create/expand network buffers.
- // In/Out are always created in a pair with identical settings so only
- // need to test one to determine what needs to be done for both.
- int netBufSize = sslEngine.getSession().getPacketBufferSize();
+ // Create the network input buffer as data needs to be read into this
+ // to be able to peek at it.
if (netInBuffer == null) {
if (sp.getDirectSslBuffer()) {
- netInBuffer = ByteBuffer.allocateDirect(netBufSize);
- netOutBuffer = ByteBuffer.allocateDirect(netBufSize);
+ netInBuffer = ByteBuffer.allocateDirect(DEFAULT_NET_BUFFER_SIZE);
} else {
- netInBuffer = ByteBuffer.allocate(netBufSize);
- netOutBuffer = ByteBuffer.allocate(netBufSize);
+ netInBuffer = ByteBuffer.allocate(DEFAULT_NET_BUFFER_SIZE);
}
- } else if (netInBuffer.capacity() < netBufSize) {
- // Need to expand the buffers, making sure no data is lost.
- ByteBuffer newInBuffer;
- ByteBuffer newOutBuffer;
- if (sp.getDirectSslBuffer()) {
- newInBuffer = ByteBuffer.allocateDirect(netBufSize);
- newOutBuffer = ByteBuffer.allocateDirect(netBufSize);
- } else {
- newInBuffer = ByteBuffer.allocate(netBufSize);
- newOutBuffer = ByteBuffer.allocate(netBufSize);
- }
- newInBuffer.put(netInBuffer);
- newOutBuffer.put(netOutBuffer);
- netInBuffer = newInBuffer;
- netOutBuffer = newOutBuffer;
- } else {
- // Existing buffers are big enough. Nothing to do here.
}
+
+ sc.read(netInBuffer);
+ SNIExtractor extractor = new SNIExtractor(netInBuffer);
+
+ String hostName = null;
+ switch (extractor.getResult()) {
+ case FOUND:
+ hostName = extractor.getSNIValue();
+ break;
+ case ERROR:
+ // NO-OP Let the handshake continue and deal with whatever was wrong
+ break;
+ case NOT_PRESENT:
+ // NO-OP
+ break;
+ case UNDERFLOW:
+ return SelectionKey.OP_READ;
+ }
+
+ System.out.println("SNI hostname was [" + hostName + "]");
+
+ // TODO: Extract the correct configuration for the requested host name
+ // and set up the SSLEngine accordingly.
+
+ sslEngine = endpoint.createSSLEngine();
+
+ // Ensure the application buffers (which have to be created earlier) are
+ // big enough.
+ bufHandler.expand(sslEngine.getSession().getApplicationBufferSize());
+ expandNetBuffers(sslEngine.getSession().getPacketBufferSize(), sp.getDirectSslBuffer());
+
// Set limit and position to expected values
- netInBuffer.position(0);
- netInBuffer.limit(0);
netOutBuffer.position(0);
netOutBuffer.limit(0);
@@ -266,6 +273,48 @@ public class SecureNioChannel extends Ni
}
+ private void expandNetBuffers(int newSize, boolean direct) {
+
+ // The input buffer will always have been created by the time this
+ // method is called.
+ if (netInBuffer.capacity() < newSize) {
+ // Info as we may need to increase DEFAULT_NET_BUFFER_SIZE
+ log.info(sm.getString("channel.nio.ssl.expandNetInBuffer", Integer.toString(newSize)));
+ ByteBuffer newInBuffer;
+ if (direct) {
+ newInBuffer = ByteBuffer.allocateDirect(newSize);
+ } else {
+ newInBuffer = ByteBuffer.allocate(newSize);
+ }
+ // Need to expand the buffers, making sure no data is lost.
+ netInBuffer.flip();
+ newInBuffer.put(netInBuffer);
+ netInBuffer = newInBuffer;
+ }
+
+ if (netOutBuffer == null) {
+ if (direct) {
+ netOutBuffer = ByteBuffer.allocateDirect(newSize);
+ } else {
+ netOutBuffer = ByteBuffer.allocate(newSize);
+ }
+ } else if (netOutBuffer.capacity() < newSize) {
+ // Info as we may need to increase DEFAULT_NET_BUFFER_SIZE
+ log.info(sm.getString("channel.nio.ssl.expandNetOutBuffer", Integer.toString(newSize)));
+ // Need to expand the buffers, making sure no data is lost.
+ ByteBuffer newOutBuffer;
+ if (direct) {
+ newOutBuffer = ByteBuffer.allocateDirect(newSize);
+ } else {
+ newOutBuffer = ByteBuffer.allocate(newSize);
+ }
+ netOutBuffer.flip();
+ newOutBuffer.put(netOutBuffer);
+ netOutBuffer = newOutBuffer;
+ }
+ }
+
+
/**
* Force a blocking handshake to take place for this key.
* This requires that both network and application buffers have been emptied out prior to this call taking place, or a
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org