Added JavaDoc to handler.ssl package
This commit is contained in:
parent
5a1f62f419
commit
f0c2c95c32
@ -24,12 +24,26 @@ package org.jboss.netty.handler.ssl;
|
|||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLEngine;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* A {@link ByteBuffer} pool dedicated for {@link SslHandler} performance
|
||||||
|
* improvement.
|
||||||
|
* <p>
|
||||||
|
* In most cases, you won't need to create a new pool instance because
|
||||||
|
* {@link SslHandler} has a default pool instance internally.
|
||||||
|
* <p>
|
||||||
|
* The reason why {@link SslHandler} requires a buffer pool is because the
|
||||||
|
* current {@link SSLEngine} implementation always requires a 17KiB buffer for
|
||||||
|
* the 'wrap' and 'unwrap' operation. In most cases, the size of the required
|
||||||
|
* buffer is much smaller than that, and therefore allocating a 17KiB buffer
|
||||||
|
* for every 'wrap' and 'unwrap' operation wastes a lot of memory bandwidth,
|
||||||
|
* resulting in the application performance degradation.
|
||||||
|
*
|
||||||
* @author The Netty Project (netty-dev@lists.jboss.org)
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
* @author Trustin Lee (tlee@redhat.com)
|
* @author Trustin Lee (tlee@redhat.com)
|
||||||
*
|
*
|
||||||
* @version $Rev$, $Date$
|
* @version $Rev$, $Date$
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class SslBufferPool {
|
public class SslBufferPool {
|
||||||
|
|
||||||
@ -41,29 +55,49 @@ public class SslBufferPool {
|
|||||||
private final int maxBufferCount;
|
private final int maxBufferCount;
|
||||||
private int index;
|
private int index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new buffer pool whose size is {@code 18113536}, which can
|
||||||
|
* hold {@code 1024} buffers.
|
||||||
|
*/
|
||||||
public SslBufferPool() {
|
public SslBufferPool() {
|
||||||
this(DEFAULT_POOL_SIZE);
|
this(DEFAULT_POOL_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SslBufferPool(int poolSize) {
|
/**
|
||||||
if (poolSize <= 0) {
|
* Creates a new buffer pool.
|
||||||
throw new IllegalArgumentException("poolSize: " + poolSize);
|
*
|
||||||
|
* @param maxPoolSize the maximum number of bytes that this pool can hold
|
||||||
|
*/
|
||||||
|
public SslBufferPool(int maxPoolSize) {
|
||||||
|
if (maxPoolSize <= 0) {
|
||||||
|
throw new IllegalArgumentException("maxPoolSize: " + maxPoolSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
int maxBufferCount = poolSize / MAX_PACKET_SIZE;
|
int maxBufferCount = maxPoolSize / MAX_PACKET_SIZE;
|
||||||
if (poolSize % MAX_PACKET_SIZE != 0) {
|
if (maxPoolSize % MAX_PACKET_SIZE != 0) {
|
||||||
maxBufferCount ++;
|
maxBufferCount ++;
|
||||||
}
|
}
|
||||||
poolSize = maxBufferCount * MAX_PACKET_SIZE;
|
maxPoolSize = maxBufferCount * MAX_PACKET_SIZE;
|
||||||
|
|
||||||
pool = new ByteBuffer[maxBufferCount];
|
pool = new ByteBuffer[maxBufferCount];
|
||||||
this.maxBufferCount = maxBufferCount;
|
this.maxBufferCount = maxBufferCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the maximum size of this pool in byte unit. The returned value
|
||||||
|
* can be somewhat different from what was specified in the constructor.
|
||||||
|
*/
|
||||||
public int getMaxPoolSize() {
|
public int getMaxPoolSize() {
|
||||||
return maxBufferCount * MAX_PACKET_SIZE;
|
return maxBufferCount * MAX_PACKET_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of bytes which were allocated but not acquired yet.
|
||||||
|
* You can estimate how optimal the specified maximum pool size is from
|
||||||
|
* this value. If it keeps returning {@code 0}, it means the pool is
|
||||||
|
* getting exhausted. If it keeps returns a unnecessarily big value, it
|
||||||
|
* means the pool is wasting the heap space.
|
||||||
|
*/
|
||||||
public synchronized int getUnacquiredPoolSize() {
|
public synchronized int getUnacquiredPoolSize() {
|
||||||
return index * MAX_PACKET_SIZE;
|
return index * MAX_PACKET_SIZE;
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ import org.jboss.netty.channel.ChannelEvent;
|
|||||||
import org.jboss.netty.channel.ChannelFuture;
|
import org.jboss.netty.channel.ChannelFuture;
|
||||||
import org.jboss.netty.channel.ChannelFutureListener;
|
import org.jboss.netty.channel.ChannelFutureListener;
|
||||||
import org.jboss.netty.channel.ChannelHandlerContext;
|
import org.jboss.netty.channel.ChannelHandlerContext;
|
||||||
|
import org.jboss.netty.channel.ChannelPipeline;
|
||||||
import org.jboss.netty.channel.ChannelStateEvent;
|
import org.jboss.netty.channel.ChannelStateEvent;
|
||||||
import org.jboss.netty.channel.Channels;
|
import org.jboss.netty.channel.Channels;
|
||||||
import org.jboss.netty.channel.MessageEvent;
|
import org.jboss.netty.channel.MessageEvent;
|
||||||
@ -51,6 +52,42 @@ import org.jboss.netty.handler.codec.frame.FrameDecoder;
|
|||||||
import org.jboss.netty.util.ImmediateExecutor;
|
import org.jboss.netty.util.ImmediateExecutor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Adds <a href="http://en.wikipedia.org/wiki/Transport_Layer_Security">SSL
|
||||||
|
* · TLS</a> and StartTLS support to a {@link Channel}. Please refer
|
||||||
|
* to the <strong>"SecureChat"</strong> example in the distribution or the web
|
||||||
|
* site for the detailed usage.
|
||||||
|
*
|
||||||
|
* <h3>Beginning the handshake</h3>
|
||||||
|
* <p>
|
||||||
|
* A user should make sure not to write a message while the
|
||||||
|
* {@linkplain #handshake(Channel) handshake} is in progress unless it's a
|
||||||
|
* renegotiation. You will be notified by the {@link ChannelFuture} which is
|
||||||
|
* returned by the {@link #handshake(Channel)} method when the handshake
|
||||||
|
* process succeeds or fails.
|
||||||
|
*
|
||||||
|
* <h3>Renegotiation</h3>
|
||||||
|
* <p>
|
||||||
|
* Once the initial handshake is done successfully. You can always call
|
||||||
|
* {@link #handshake(Channel)} again to renegotiate the SSL session parameters.
|
||||||
|
*
|
||||||
|
* <h3>Closing the session</h3>
|
||||||
|
* <p>
|
||||||
|
* To close the SSL session, the {@link #close(Channel)} method should be
|
||||||
|
* called to send the {@code close_notify} message to the remote peer. One
|
||||||
|
* exception is when you close the {@link Channel} - {@link SslHandler}
|
||||||
|
* intercepts the close request and send the {@code close_notify} message
|
||||||
|
* before the channel closure automatically. Once the SSL session is closed,
|
||||||
|
* it's not reusable, and consequently you should create a new
|
||||||
|
* {@link SslHandler} with a new {@link SSLEngine} as explained in the
|
||||||
|
* following section.
|
||||||
|
*
|
||||||
|
* <h3>Restarting the session</h3>
|
||||||
|
* <p>
|
||||||
|
* To restart the SSL session, you must remove the existing closed
|
||||||
|
* {@link SslHandler} from the {@link ChannelPipeline}, insert a new
|
||||||
|
* {@link SslHandler} with a new {@link SSLEngine} into the pipeline,
|
||||||
|
* and start the handshake process as described in the first section.
|
||||||
|
*
|
||||||
* @author The Netty Project (netty-dev@lists.jboss.org)
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
* @author Trustin Lee (tlee@redhat.com)
|
* @author Trustin Lee (tlee@redhat.com)
|
||||||
*
|
*
|
||||||
@ -65,7 +102,11 @@ public class SslHandler extends FrameDecoder implements ChannelDownstreamHandler
|
|||||||
|
|
||||||
private static SslBufferPool defaultBufferPool;
|
private static SslBufferPool defaultBufferPool;
|
||||||
|
|
||||||
private static synchronized SslBufferPool getDefaultBufferPool() {
|
/**
|
||||||
|
* Returns the default {@link SslBufferPool} used when no pool is
|
||||||
|
* specified in the constructor.
|
||||||
|
*/
|
||||||
|
public static synchronized SslBufferPool getDefaultBufferPool() {
|
||||||
if (defaultBufferPool == null) {
|
if (defaultBufferPool == null) {
|
||||||
defaultBufferPool = new SslBufferPool();
|
defaultBufferPool = new SslBufferPool();
|
||||||
}
|
}
|
||||||
@ -88,34 +129,110 @@ public class SslHandler extends FrameDecoder implements ChannelDownstreamHandler
|
|||||||
private final Queue<PendingWrite> pendingUnencryptedWrites = new LinkedList<PendingWrite>();
|
private final Queue<PendingWrite> pendingUnencryptedWrites = new LinkedList<PendingWrite>();
|
||||||
private final Queue<MessageEvent> pendingEncryptedWrites = new LinkedList<MessageEvent>();
|
private final Queue<MessageEvent> pendingEncryptedWrites = new LinkedList<MessageEvent>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
*
|
||||||
|
* @param engine the {@link SSLEngine} this handler will use
|
||||||
|
*/
|
||||||
public SslHandler(SSLEngine engine) {
|
public SslHandler(SSLEngine engine) {
|
||||||
this(engine, getDefaultBufferPool(), ImmediateExecutor.INSTANCE);
|
this(engine, getDefaultBufferPool(), ImmediateExecutor.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
*
|
||||||
|
* @param engine the {@link SSLEngine} this handler will use
|
||||||
|
* @param bufferPool the {@link SslBufferPool} where this handler will
|
||||||
|
* acquire the buffers required by the {@link SSLEngine}
|
||||||
|
*/
|
||||||
public SslHandler(SSLEngine engine, SslBufferPool bufferPool) {
|
public SslHandler(SSLEngine engine, SslBufferPool bufferPool) {
|
||||||
this(engine, bufferPool, ImmediateExecutor.INSTANCE);
|
this(engine, bufferPool, ImmediateExecutor.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
*
|
||||||
|
* @param engine the {@link SSLEngine} this handler will use
|
||||||
|
* @param startTls {@code true} if the first write request shouldn't be
|
||||||
|
* encrypted by the {@link SSLEngine}
|
||||||
|
*/
|
||||||
public SslHandler(SSLEngine engine, boolean startTls) {
|
public SslHandler(SSLEngine engine, boolean startTls) {
|
||||||
this(engine, getDefaultBufferPool(), startTls);
|
this(engine, getDefaultBufferPool(), startTls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
*
|
||||||
|
* @param engine the {@link SSLEngine} this handler will use
|
||||||
|
* @param bufferPool the {@link SslBufferPool} where this handler will
|
||||||
|
* acquire the buffers required by the {@link SSLEngine}
|
||||||
|
* @param startTls {@code true} if the first write request shouldn't be
|
||||||
|
* encrypted by the {@link SSLEngine}
|
||||||
|
*/
|
||||||
public SslHandler(SSLEngine engine, SslBufferPool bufferPool, boolean startTls) {
|
public SslHandler(SSLEngine engine, SslBufferPool bufferPool, boolean startTls) {
|
||||||
this(engine, bufferPool, startTls, ImmediateExecutor.INSTANCE);
|
this(engine, bufferPool, startTls, ImmediateExecutor.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
*
|
||||||
|
* @param engine
|
||||||
|
* the {@link SSLEngine} this handler will use
|
||||||
|
* @param delegatedTaskExecutor
|
||||||
|
* the {@link Executor} which will execute the delegated task
|
||||||
|
* that {@link SSLEngine#getDelegatedTask()} will return
|
||||||
|
*/
|
||||||
public SslHandler(SSLEngine engine, Executor delegatedTaskExecutor) {
|
public SslHandler(SSLEngine engine, Executor delegatedTaskExecutor) {
|
||||||
this(engine, getDefaultBufferPool(), delegatedTaskExecutor);
|
this(engine, getDefaultBufferPool(), delegatedTaskExecutor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
*
|
||||||
|
* @param engine
|
||||||
|
* the {@link SSLEngine} this handler will use
|
||||||
|
* @param bufferPool
|
||||||
|
* the {@link SslBufferPool} where this handler will acquire
|
||||||
|
* the buffers required by the {@link SSLEngine}
|
||||||
|
* @param delegatedTaskExecutor
|
||||||
|
* the {@link Executor} which will execute the delegated task
|
||||||
|
* that {@link SSLEngine#getDelegatedTask()} will return
|
||||||
|
*/
|
||||||
public SslHandler(SSLEngine engine, SslBufferPool bufferPool, Executor delegatedTaskExecutor) {
|
public SslHandler(SSLEngine engine, SslBufferPool bufferPool, Executor delegatedTaskExecutor) {
|
||||||
this(engine, bufferPool, false, delegatedTaskExecutor);
|
this(engine, bufferPool, false, delegatedTaskExecutor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
*
|
||||||
|
* @param engine
|
||||||
|
* the {@link SSLEngine} this handler will use
|
||||||
|
* @param startTls
|
||||||
|
* {@code true} if the first write request shouldn't be encrypted
|
||||||
|
* by the {@link SSLEngine}
|
||||||
|
* @param delegatedTaskExecutor
|
||||||
|
* the {@link Executor} which will execute the delegated task
|
||||||
|
* that {@link SSLEngine#getDelegatedTask()} will return
|
||||||
|
*/
|
||||||
public SslHandler(SSLEngine engine, boolean startTls, Executor delegatedTaskExecutor) {
|
public SslHandler(SSLEngine engine, boolean startTls, Executor delegatedTaskExecutor) {
|
||||||
this(engine, getDefaultBufferPool(), startTls, delegatedTaskExecutor);
|
this(engine, getDefaultBufferPool(), startTls, delegatedTaskExecutor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
*
|
||||||
|
* @param engine
|
||||||
|
* the {@link SSLEngine} this handler will use
|
||||||
|
* @param bufferPool
|
||||||
|
* the {@link SslBufferPool} where this handler will acquire
|
||||||
|
* the buffers required by the {@link SSLEngine}
|
||||||
|
* @param startTls
|
||||||
|
* {@code true} if the first write request shouldn't be encrypted
|
||||||
|
* by the {@link SSLEngine}
|
||||||
|
* @param delegatedTaskExecutor
|
||||||
|
* the {@link Executor} which will execute the delegated task
|
||||||
|
* that {@link SSLEngine#getDelegatedTask()} will return
|
||||||
|
*/
|
||||||
public SslHandler(SSLEngine engine, SslBufferPool bufferPool, boolean startTls, Executor delegatedTaskExecutor) {
|
public SslHandler(SSLEngine engine, SslBufferPool bufferPool, boolean startTls, Executor delegatedTaskExecutor) {
|
||||||
if (engine == null) {
|
if (engine == null) {
|
||||||
throw new NullPointerException("engine");
|
throw new NullPointerException("engine");
|
||||||
@ -132,10 +249,19 @@ public class SslHandler extends FrameDecoder implements ChannelDownstreamHandler
|
|||||||
this.startTls = startTls;
|
this.startTls = startTls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link SSLEngine} which is used by this handler.
|
||||||
|
*/
|
||||||
public SSLEngine getEngine() {
|
public SSLEngine getEngine() {
|
||||||
return engine;
|
return engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts SSL / TLS handshake for the specified channel.
|
||||||
|
*
|
||||||
|
* @return a {@link ChannelFuture} which is notified when the handshake
|
||||||
|
* succeeds or fails.
|
||||||
|
*/
|
||||||
public ChannelFuture handshake(Channel channel) throws SSLException {
|
public ChannelFuture handshake(Channel channel) throws SSLException {
|
||||||
ChannelFuture handshakeFuture;
|
ChannelFuture handshakeFuture;
|
||||||
synchronized (handshakeLock) {
|
synchronized (handshakeLock) {
|
||||||
@ -153,6 +279,10 @@ public class SslHandler extends FrameDecoder implements ChannelDownstreamHandler
|
|||||||
return handshakeFuture;
|
return handshakeFuture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a SSL {@code close_notify} message to the specified channel and
|
||||||
|
* destroys the underlying {@link SSLEngine}.
|
||||||
|
*/
|
||||||
public ChannelFuture close(Channel channel) throws SSLException {
|
public ChannelFuture close(Channel channel) throws SSLException {
|
||||||
ChannelHandlerContext ctx = context(channel);
|
ChannelHandlerContext ctx = context(channel);
|
||||||
engine.closeOutbound();
|
engine.closeOutbound();
|
||||||
|
@ -23,6 +23,6 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* <a href="http://en.wikipedia.org/wiki/Transport_Layer_Security">SSL ·
|
* <a href="http://en.wikipedia.org/wiki/Transport_Layer_Security">SSL ·
|
||||||
* TLS</a> implementation.
|
* TLS</a> implementation based on {@link javax.net.ssl.SSLEngine}
|
||||||
*/
|
*/
|
||||||
package org.jboss.netty.handler.ssl;
|
package org.jboss.netty.handler.ssl;
|
Loading…
Reference in New Issue
Block a user