private static final ByteBuffer __FILL_CALLED_FLUSH= BufferUtil.allocate(0);
private static final ByteBuffer __FLUSH_CALLED_FILL= BufferUtil.allocate(0);
private final ByteBufferPool _bufferPool;
- private final SSLEngine _sslEngine;
+ private SSLEngine _sslEngine;
+ private final SslReconfigurator _sslFactory;
private final DecryptedEndPoint _decryptedEndPoint;
private ByteBuffer _decryptedInput;
private ByteBuffer _encryptedInput;
private boolean _renegotiationAllowed;
public SslConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, SSLEngine sslEngine)
+ {
+ this(byteBufferPool, executor, endPoint, sslEngine, null);
+ }
+ public SslConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, SSLEngine sslEngine, SslReconfigurator fact)
{
// This connection does not execute calls to onfillable, so they will be called by the selector thread.
// onfillable does not block and will only wakeup another thread to do the actual reading and handling.
super(endPoint, executor, !EXECUTE_ONFILLABLE);
this._bufferPool = byteBufferPool;
this._sslEngine = sslEngine;
+ this._sslFactory = fact;
this._decryptedEndPoint = newDecryptedEndPoint();
}
private boolean _cannotAcceptMoreAppDataToFlush;
private boolean _handshaken;
private boolean _underFlown;
+ private boolean _peeking = _sslFactory != null;
private final Callback _writeCallback = new Callback()
{
// We will need a network buffer
if (_encryptedInput == null)
_encryptedInput = _bufferPool.acquire(_sslEngine.getSession().getPacketBufferSize(), _encryptedDirectBuffers);
- else
+ else if(!_peeking)
BufferUtil.compact(_encryptedInput);
// We also need an app buffer, but can use the passed buffer if it is big enough
case NEED_TASK:
{
_sslEngine.getDelegatedTask().run();
+ if(_peeking)
+ {
+ _sslEngine = _sslFactory.restartSSL(_sslEngine.getHandshakeSession());
+ _encryptedInput.position(0);
+ _peeking = false;
+ continue decryption;
+ }
continue;
}
case NEED_WRAP:
--- /dev/null
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.io.ssl;
+
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSession;
+
+public interface SslReconfigurator {
+ public boolean shouldRestartSSL();
+
+ public SSLEngine restartSSL(SSLSession sslSession);
+
+}
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.ssl.SslConnection;
+import org.eclipse.jetty.io.ssl.SslReconfigurator;
import org.eclipse.jetty.util.annotation.Name;
import org.eclipse.jetty.util.ssl.SslContextFactory;
-public class SslConnectionFactory extends AbstractConnectionFactory
+public class SslConnectionFactory extends AbstractConnectionFactory implements SslReconfigurator
{
private final SslContextFactory _sslContextFactory;
private final String _nextProtocol;
protected SslConnection newSslConnection(Connector connector, EndPoint endPoint, SSLEngine engine)
{
- return new SslConnection(connector.getByteBufferPool(), connector.getExecutor(), endPoint, engine);
+ return new SslConnection(connector.getByteBufferPool(), connector.getExecutor(), endPoint, engine, shouldRestartSSL()?this:null);
+ }
+
+ public boolean shouldRestartSSL(){
+ return false;
+ }
+
+ public SSLEngine restartSSL(SSLSession sslSession){
+ throw new UnsupportedOperationException();
}
@Override