Class SslHandler
- java.lang.Object
-
- io.netty.channel.ChannelHandlerAdapter
-
- io.netty.channel.ChannelInboundHandlerAdapter
-
- io.netty.handler.codec.ByteToMessageDecoder
-
- io.netty.handler.ssl.SslHandler
-
- All Implemented Interfaces:
ChannelHandler
,ChannelInboundHandler
,ChannelOutboundHandler
public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundHandler
Adds SSL · TLS and StartTLS support to aChannel
. Please refer to the "SecureChat" example in the distribution or the web site for the detailed usage.Beginning the handshake
Beside using the handshake
ChannelFuture
to get notified about the completion of the handshake it's also possible to detect it by implement theChannelInboundHandler.userEventTriggered(ChannelHandlerContext, Object)
method and check for aSslHandshakeCompletionEvent
.Handshake
The handshake will be automatically issued for you once the
Channel
is active andSSLEngine.getUseClientMode()
returnstrue
. So no need to bother with it by your self.Closing the session
To close the SSL session, the
closeOutbound()
method should be called to send theclose_notify
message to the remote peer. One exception is when you close theChannel
-SslHandler
intercepts the close request and send theclose_notify
message before the channel closure automatically. Once the SSL session is closed, it is not reusable, and consequently you should create a newSslHandler
with a newSSLEngine
as explained in the following section.Restarting the session
To restart the SSL session, you must remove the existing closed
SslHandler
from theChannelPipeline
, insert a newSslHandler
with a newSSLEngine
into the pipeline, and start the handshake process as described in the first section.Implementing StartTLS
StartTLS is the communication pattern that secures the wire in the middle of the plaintext connection. Please note that it is different from SSL · TLS, that secures the wire from the beginning of the connection. Typically, StartTLS is composed of three steps:
- Client sends a StartTLS request to server.
- Server sends a StartTLS response to client.
- Client begins SSL handshake.
- create a new
SslHandler
instance withstartTls
flag set totrue
, - insert the
SslHandler
to theChannelPipeline
, and - write a StartTLS response.
SslHandler
before sending the StartTLS response. Otherwise the client can send begin SSL handshake beforeSslHandler
is inserted to theChannelPipeline
, causing data corruption.The client-side implementation is much simpler.
- Write a StartTLS request,
- wait for the StartTLS response,
- create a new
SslHandler
instance withstartTls
flag set tofalse
, - insert the
SslHandler
to theChannelPipeline
, and - Initiate SSL handshake.
Known issues
Because of a known issue with the current implementation of the SslEngine that comes with Java it may be possible that you see blocked IO-Threads while a full GC is done.
So if you are affected you can workaround this problem by adjust the cache settings like shown below:
SslContext context = ...; context.getServerSessionContext().setSessionCacheSize(someSaneSize); context.getServerSessionContext().setSessionTime(someSameTimeout);
What values to use here depends on the nature of your application and should be set based on monitoring and debugging of it. For more details see #832 in our issue tracker.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private class
SslHandler.LazyChannelPromise
private static class
SslHandler.SslEngineType
private class
SslHandler.SslHandlerCoalescingBufferQueue
Each call to SSL_write will introduce about ~100 bytes of overhead.private class
SslHandler.SslTasksRunner
Runnable
that will be scheduled on thedelegatedTaskExecutor
and will take care of resume work on theEventExecutor
once the task was executed.-
Nested classes/interfaces inherited from class io.netty.handler.codec.ByteToMessageDecoder
ByteToMessageDecoder.Cumulator
-
Nested classes/interfaces inherited from interface io.netty.channel.ChannelHandler
ChannelHandler.Sharable
-
-
Field Summary
Fields Modifier and Type Field Description private boolean
closeNotify
private long
closeNotifyFlushTimeoutMillis
private long
closeNotifyReadTimeoutMillis
private ChannelHandlerContext
ctx
private java.util.concurrent.Executor
delegatedTaskExecutor
private javax.net.ssl.SSLEngine
engine
private SslHandler.SslEngineType
engineType
private boolean
firedChannelRead
This flag is used to determine if we need to callChannelHandlerContext.read()
to consume more data whenChannelConfig.isAutoRead()
isfalse
.private boolean
flushedBeforeHandshake
private Promise<Channel>
handshakePromise
private boolean
handshakeStarted
private long
handshakeTimeoutMillis
private static java.util.regex.Pattern
IGNORABLE_CLASS_IN_STACK
private static java.util.regex.Pattern
IGNORABLE_ERROR_MESSAGE
private boolean
jdkCompatibilityMode
private static InternalLogger
logger
private static int
MAX_PLAINTEXT_LENGTH
2^14 which is the maximum sized plaintext chunk allowed by the TLS RFC.private boolean
needsFlush
Set by wrap*() methods when something is produced.private boolean
outboundClosed
private int
packetLength
private SslHandler.SslHandlerCoalescingBufferQueue
pendingUnencryptedWrites
private boolean
processTask
private boolean
readDuringHandshake
private boolean
sentFirstMessage
private java.nio.ByteBuffer[]
singleBuffer
Used ifSSLEngine.wrap(ByteBuffer[], ByteBuffer)
andSSLEngine.unwrap(ByteBuffer, ByteBuffer[])
should be called with aByteBuf
that is only backed by oneByteBuffer
to reduce the object creation.private SslHandler.LazyChannelPromise
sslClosePromise
private boolean
startTls
(package private) int
wrapDataSize
-
Fields inherited from class io.netty.handler.codec.ByteToMessageDecoder
COMPOSITE_CUMULATOR, MERGE_CUMULATOR
-
-
Constructor Summary
Constructors Constructor Description SslHandler(javax.net.ssl.SSLEngine engine)
Creates a new instance which runs all delegated tasks directly on theEventExecutor
.SslHandler(javax.net.ssl.SSLEngine engine, boolean startTls)
Creates a new instance which runs all delegated tasks directly on theEventExecutor
.SslHandler(javax.net.ssl.SSLEngine engine, boolean startTls, java.util.concurrent.Executor delegatedTaskExecutor)
Creates a new instance.SslHandler(javax.net.ssl.SSLEngine engine, java.util.concurrent.Executor delegatedTaskExecutor)
Creates a new instance.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods Modifier and Type Method Description private static void
addCloseListener(ChannelFuture future, ChannelPromise promise)
private ByteBuf
allocate(ChannelHandlerContext ctx, int capacity)
Always prefer a direct buffer when it's pooled, so that we reduce the number of memory copies inOpenSslEngine
.private ByteBuf
allocateOutNetBuf(ChannelHandlerContext ctx, int pendingBytes, int numComponents)
Allocates an outbound network buffer forSSLEngine.wrap(ByteBuffer, ByteBuffer)
which can encrypt the specified amount of pending bytes.java.lang.String
applicationProtocol()
Returns the name of the current application-level protocol.private void
applyHandshakeTimeout()
private static boolean
attemptCopyToCumulation(ByteBuf cumulation, ByteBuf next, int wrapDataSize)
void
bind(ChannelHandlerContext ctx, java.net.SocketAddress localAddress, ChannelPromise promise)
Called once a bind operation is made.void
channelActive(ChannelHandlerContext ctx)
Issues an initial TLS handshake once connected when used in client-modevoid
channelInactive(ChannelHandlerContext ctx)
CallsChannelHandlerContext.fireChannelInactive()
to forward to the nextChannelInboundHandler
in theChannelPipeline
.void
channelReadComplete(ChannelHandlerContext ctx)
CallsChannelHandlerContext.fireChannelReadComplete()
to forward to the nextChannelInboundHandler
in theChannelPipeline
.private void
channelReadComplete0(ChannelHandlerContext ctx)
ChannelFuture
close()
Deprecated.void
close(ChannelHandlerContext ctx, ChannelPromise promise)
Called once a close operation is made.ChannelFuture
close(ChannelPromise promise)
Deprecated.ChannelFuture
closeOutbound()
Sends an SSLclose_notify
message to the specified channel and destroys the underlyingSSLEngine
.ChannelFuture
closeOutbound(ChannelPromise promise)
Sends an SSLclose_notify
message to the specified channel and destroys the underlyingSSLEngine
.private void
closeOutbound0(ChannelPromise promise)
private void
closeOutboundAndChannel(ChannelHandlerContext ctx, ChannelPromise promise, boolean disconnect)
void
connect(ChannelHandlerContext ctx, java.net.SocketAddress remoteAddress, java.net.SocketAddress localAddress, ChannelPromise promise)
Called once a connect operation is made.protected void
decode(ChannelHandlerContext ctx, ByteBuf in, java.util.List<java.lang.Object> out)
Decode the from oneByteBuf
to an other.private void
decodeJdkCompatible(ChannelHandlerContext ctx, ByteBuf in)
private void
decodeNonJdkCompatible(ChannelHandlerContext ctx, ByteBuf in)
void
deregister(ChannelHandlerContext ctx, ChannelPromise promise)
Called once a deregister operation is made from the current registeredEventLoop
.void
disconnect(ChannelHandlerContext ctx, ChannelPromise promise)
Called once a disconnect operation is made.javax.net.ssl.SSLEngine
engine()
Returns theSSLEngine
which is used by this handler.void
exceptionCaught(ChannelHandlerContext ctx, java.lang.Throwable cause)
CallsChannelHandlerContext.fireExceptionCaught(Throwable)
to forward to the nextChannelHandler
in theChannelPipeline
.private void
executeDelegatedTasks(boolean inUnwrap)
private void
finishWrap(ChannelHandlerContext ctx, ByteBuf out, ChannelPromise promise, boolean inUnwrap, boolean needUnwrap)
void
flush(ChannelHandlerContext ctx)
Called once a flush operation is made.private void
flush(ChannelHandlerContext ctx, ChannelPromise promise)
private void
flushIfNeeded(ChannelHandlerContext ctx)
private void
forceFlush(ChannelHandlerContext ctx)
long
getCloseNotifyFlushTimeoutMillis()
Gets the timeout for flushing the close_notify that was triggered by closing theChannel
.long
getCloseNotifyReadTimeoutMillis()
Gets the timeout (in ms) for receiving the response for the close_notify that was triggered by closing theChannel
.long
getCloseNotifyTimeoutMillis()
Deprecated.long
getHandshakeTimeoutMillis()
void
handlerAdded(ChannelHandlerContext ctx)
Do nothing by default, sub-classes may override this method.void
handlerRemoved0(ChannelHandlerContext ctx)
Gets called after theByteToMessageDecoder
was removed from the actual context and it doesn't handle events anymore.private void
handleUnwrapThrowable(ChannelHandlerContext ctx, java.lang.Throwable cause)
private void
handshake()
Performs TLS (re)negotiation.Future<Channel>
handshakeFuture()
Returns aFuture
that will get notified once the current TLS handshake completes.private boolean
ignoreException(java.lang.Throwable t)
Checks if the givenThrowable
can be ignore and just "swallowed" When an ssl connection is closed a close_notify message is sent.private static boolean
inEventLoop(java.util.concurrent.Executor executor)
static boolean
isEncrypted(ByteBuf buffer)
Returnstrue
if the givenByteBuf
is encrypted.private static java.lang.IllegalStateException
newPendingWritesNullException()
private void
notifyClosePromise(java.lang.Throwable cause)
void
read(ChannelHandlerContext ctx)
InterceptsChannelHandlerContext.read()
.private void
readIfNeeded(ChannelHandlerContext ctx)
private void
releaseAndFailAll(ChannelHandlerContext ctx, java.lang.Throwable cause)
Future<Channel>
renegotiate()
Performs TLS renegotiation.Future<Channel>
renegotiate(Promise<Channel> promise)
Performs TLS renegotiation.private void
renegotiateOnEventLoop(Promise<Channel> newHandshakePromise)
private static void
runAllDelegatedTasks(javax.net.ssl.SSLEngine engine)
private boolean
runDelegatedTasks(boolean inUnwrap)
Will either run the delegated task directly callingRunnable.run()
and returntrue
or will offload the delegated task usingExecutor.execute(Runnable)
and returnfalse
.private void
safeClose(ChannelHandlerContext ctx, ChannelFuture flushFuture, ChannelPromise promise)
void
setCloseNotifyFlushTimeout(long closeNotifyFlushTimeout, java.util.concurrent.TimeUnit unit)
Sets the timeout for flushing the close_notify that was triggered by closing theChannel
.void
setCloseNotifyFlushTimeoutMillis(long closeNotifyFlushTimeoutMillis)
void
setCloseNotifyReadTimeout(long closeNotifyReadTimeout, java.util.concurrent.TimeUnit unit)
Sets the timeout for receiving the response for the close_notify that was triggered by closing theChannel
.void
setCloseNotifyReadTimeoutMillis(long closeNotifyReadTimeoutMillis)
void
setCloseNotifyTimeout(long closeNotifyTimeout, java.util.concurrent.TimeUnit unit)
Deprecated.void
setCloseNotifyTimeoutMillis(long closeNotifyFlushTimeoutMillis)
Deprecated.private void
setHandshakeFailure(ChannelHandlerContext ctx, java.lang.Throwable cause)
Notify all the handshake futures about the failure during the handshake.private void
setHandshakeFailure(ChannelHandlerContext ctx, java.lang.Throwable cause, boolean closeInbound, boolean notify, boolean alwaysFlushAndClose)
Notify all the handshake futures about the failure during the handshake.private void
setHandshakeFailureTransportFailure(ChannelHandlerContext ctx, java.lang.Throwable cause)
private void
setHandshakeSuccess()
Notify all the handshake futures about the successfully handshakeprivate boolean
setHandshakeSuccessIfStillHandshaking()
Works around some AndroidSSLEngine
implementations that skipSSLEngineResult.HandshakeStatus.FINISHED
and go straight intoSSLEngineResult.HandshakeStatus.NOT_HANDSHAKING
when handshake is finished.void
setHandshakeTimeout(long handshakeTimeout, java.util.concurrent.TimeUnit unit)
void
setHandshakeTimeoutMillis(long handshakeTimeoutMillis)
void
setWrapDataSize(int wrapDataSize)
Sets the number of bytes to pass to eachSSLEngine.wrap(ByteBuffer[], int, int, ByteBuffer)
call.Future<Channel>
sslCloseFuture()
Return theFuture
that will get notified if the inbound of theSSLEngine
is closed.private void
startHandshakeProcessing()
private static java.nio.ByteBuffer
toByteBuffer(ByteBuf out, int index, int len)
private int
unwrap(ChannelHandlerContext ctx, ByteBuf packet, int offset, int length)
Unwraps inbound SSL records.private void
unwrapNonAppData(ChannelHandlerContext ctx)
CallsSSLEngine.unwrap(ByteBuffer, ByteBuffer)
with an empty buffer to handle handshakes, etc.private javax.net.ssl.SSLEngineResult
wrap(ByteBufAllocator alloc, javax.net.ssl.SSLEngine engine, ByteBuf in, ByteBuf out)
private void
wrap(ChannelHandlerContext ctx, boolean inUnwrap)
private void
wrapAndFlush(ChannelHandlerContext ctx)
private boolean
wrapNonAppData(ChannelHandlerContext ctx, boolean inUnwrap)
void
write(ChannelHandlerContext ctx, java.lang.Object msg, ChannelPromise promise)
Called once a write operation is made.-
Methods inherited from class io.netty.handler.codec.ByteToMessageDecoder
actualReadableBytes, callDecode, channelRead, decodeLast, discardSomeReadBytes, handlerRemoved, internalBuffer, isSingleDecode, setCumulator, setDiscardAfterReads, setSingleDecode, userEventTriggered
-
Methods inherited from class io.netty.channel.ChannelInboundHandlerAdapter
channelRegistered, channelUnregistered, channelWritabilityChanged
-
Methods inherited from class io.netty.channel.ChannelHandlerAdapter
ensureNotSharable, isSharable
-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface io.netty.channel.ChannelHandler
handlerRemoved
-
-
-
-
Field Detail
-
logger
private static final InternalLogger logger
-
IGNORABLE_CLASS_IN_STACK
private static final java.util.regex.Pattern IGNORABLE_CLASS_IN_STACK
-
IGNORABLE_ERROR_MESSAGE
private static final java.util.regex.Pattern IGNORABLE_ERROR_MESSAGE
-
MAX_PLAINTEXT_LENGTH
private static final int MAX_PLAINTEXT_LENGTH
2^14 which is the maximum sized plaintext chunk allowed by the TLS RFC.- See Also:
- Constant Field Values
-
ctx
private volatile ChannelHandlerContext ctx
-
engine
private final javax.net.ssl.SSLEngine engine
-
engineType
private final SslHandler.SslEngineType engineType
-
delegatedTaskExecutor
private final java.util.concurrent.Executor delegatedTaskExecutor
-
jdkCompatibilityMode
private final boolean jdkCompatibilityMode
-
singleBuffer
private final java.nio.ByteBuffer[] singleBuffer
Used ifSSLEngine.wrap(ByteBuffer[], ByteBuffer)
andSSLEngine.unwrap(ByteBuffer, ByteBuffer[])
should be called with aByteBuf
that is only backed by oneByteBuffer
to reduce the object creation.
-
startTls
private final boolean startTls
-
sentFirstMessage
private boolean sentFirstMessage
-
flushedBeforeHandshake
private boolean flushedBeforeHandshake
-
readDuringHandshake
private boolean readDuringHandshake
-
handshakeStarted
private boolean handshakeStarted
-
pendingUnencryptedWrites
private SslHandler.SslHandlerCoalescingBufferQueue pendingUnencryptedWrites
-
sslClosePromise
private final SslHandler.LazyChannelPromise sslClosePromise
-
needsFlush
private boolean needsFlush
Set by wrap*() methods when something is produced.channelReadComplete(ChannelHandlerContext)
will check this flag, clear it, and call ctx.flush().
-
outboundClosed
private boolean outboundClosed
-
closeNotify
private boolean closeNotify
-
processTask
private boolean processTask
-
packetLength
private int packetLength
-
firedChannelRead
private boolean firedChannelRead
This flag is used to determine if we need to callChannelHandlerContext.read()
to consume more data whenChannelConfig.isAutoRead()
isfalse
.
-
handshakeTimeoutMillis
private volatile long handshakeTimeoutMillis
-
closeNotifyFlushTimeoutMillis
private volatile long closeNotifyFlushTimeoutMillis
-
closeNotifyReadTimeoutMillis
private volatile long closeNotifyReadTimeoutMillis
-
wrapDataSize
volatile int wrapDataSize
-
-
Constructor Detail
-
SslHandler
public SslHandler(javax.net.ssl.SSLEngine engine)
Creates a new instance which runs all delegated tasks directly on theEventExecutor
.- Parameters:
engine
- theSSLEngine
this handler will use
-
SslHandler
public SslHandler(javax.net.ssl.SSLEngine engine, boolean startTls)
Creates a new instance which runs all delegated tasks directly on theEventExecutor
.- Parameters:
engine
- theSSLEngine
this handler will usestartTls
-true
if the first write request shouldn't be encrypted by theSSLEngine
-
SslHandler
public SslHandler(javax.net.ssl.SSLEngine engine, java.util.concurrent.Executor delegatedTaskExecutor)
Creates a new instance.- Parameters:
engine
- theSSLEngine
this handler will usedelegatedTaskExecutor
- theExecutor
that will be used to execute tasks that are returned bySSLEngine.getDelegatedTask()
.
-
SslHandler
public SslHandler(javax.net.ssl.SSLEngine engine, boolean startTls, java.util.concurrent.Executor delegatedTaskExecutor)
Creates a new instance.- Parameters:
engine
- theSSLEngine
this handler will usestartTls
-true
if the first write request shouldn't be encrypted by theSSLEngine
delegatedTaskExecutor
- theExecutor
that will be used to execute tasks that are returned bySSLEngine.getDelegatedTask()
.
-
-
Method Detail
-
getHandshakeTimeoutMillis
public long getHandshakeTimeoutMillis()
-
setHandshakeTimeout
public void setHandshakeTimeout(long handshakeTimeout, java.util.concurrent.TimeUnit unit)
-
setHandshakeTimeoutMillis
public void setHandshakeTimeoutMillis(long handshakeTimeoutMillis)
-
setWrapDataSize
@UnstableApi public final void setWrapDataSize(int wrapDataSize)
Sets the number of bytes to pass to eachSSLEngine.wrap(ByteBuffer[], int, int, ByteBuffer)
call.This value will partition data which is passed to write
write(ChannelHandlerContext, Object, ChannelPromise)
. The partitioning will work as follows:- If
wrapDataSize <= 0
then we will write each data chunk as is. - If
wrapDataSize > data size
then we will attempt to aggregate multiple data chunks together. - If
wrapDataSize > data size
Else ifwrapDataSize <= data size
then we will divide the data into chunks ofwrapDataSize
when writing.
If the
SSLEngine
doesn't support a gather wrap operation (e.g.SslProvider#OPENSSL
) then aggregating data before wrapping can help reduce the ratio between TLS overhead vs data payload which will lead to better goodput. Writing fixed chunks of data can also help target the underlying transport's (e.g. TCP) frame size. Under lossy/congested network conditions this may help the peer get full TLS packets earlier and be able to do work sooner, as opposed to waiting for the all the pieces of the TLS packet to arrive.- Parameters:
wrapDataSize
- the number of bytes which will be passed to eachSSLEngine.wrap(ByteBuffer[], int, int, ByteBuffer)
call.
- If
-
getCloseNotifyTimeoutMillis
@Deprecated public long getCloseNotifyTimeoutMillis()
Deprecated.
-
setCloseNotifyTimeout
@Deprecated public void setCloseNotifyTimeout(long closeNotifyTimeout, java.util.concurrent.TimeUnit unit)
Deprecated.
-
setCloseNotifyTimeoutMillis
@Deprecated public void setCloseNotifyTimeoutMillis(long closeNotifyFlushTimeoutMillis)
Deprecated.
-
getCloseNotifyFlushTimeoutMillis
public final long getCloseNotifyFlushTimeoutMillis()
-
setCloseNotifyFlushTimeout
public final void setCloseNotifyFlushTimeout(long closeNotifyFlushTimeout, java.util.concurrent.TimeUnit unit)
-
setCloseNotifyFlushTimeoutMillis
public final void setCloseNotifyFlushTimeoutMillis(long closeNotifyFlushTimeoutMillis)
-
getCloseNotifyReadTimeoutMillis
public final long getCloseNotifyReadTimeoutMillis()
-
setCloseNotifyReadTimeout
public final void setCloseNotifyReadTimeout(long closeNotifyReadTimeout, java.util.concurrent.TimeUnit unit)
-
setCloseNotifyReadTimeoutMillis
public final void setCloseNotifyReadTimeoutMillis(long closeNotifyReadTimeoutMillis)
-
engine
public javax.net.ssl.SSLEngine engine()
Returns theSSLEngine
which is used by this handler.
-
applicationProtocol
public java.lang.String applicationProtocol()
Returns the name of the current application-level protocol.- Returns:
- the protocol name or
null
if application-level protocol has not been negotiated
-
handshakeFuture
public Future<Channel> handshakeFuture()
Returns aFuture
that will get notified once the current TLS handshake completes.- Returns:
- the
Future
for the initial TLS handshake ifrenegotiate()
was not invoked. TheFuture
for the most recent TLS renegotiation otherwise.
-
close
@Deprecated public ChannelFuture close()
Deprecated.UsecloseOutbound()
-
close
@Deprecated public ChannelFuture close(ChannelPromise promise)
Deprecated.
-
closeOutbound
public ChannelFuture closeOutbound()
Sends an SSLclose_notify
message to the specified channel and destroys the underlyingSSLEngine
. This will not close the underlyingChannel
. If you want to also close theChannel
useChannelOutboundInvoker.close()
orChannelOutboundInvoker.close()
-
closeOutbound
public ChannelFuture closeOutbound(ChannelPromise promise)
Sends an SSLclose_notify
message to the specified channel and destroys the underlyingSSLEngine
. This will not close the underlyingChannel
. If you want to also close theChannel
useChannelOutboundInvoker.close()
orChannelOutboundInvoker.close()
-
closeOutbound0
private void closeOutbound0(ChannelPromise promise)
-
sslCloseFuture
public Future<Channel> sslCloseFuture()
Return theFuture
that will get notified if the inbound of theSSLEngine
is closed. This method will return the sameFuture
all the time.- See Also:
SSLEngine
-
handlerRemoved0
public void handlerRemoved0(ChannelHandlerContext ctx) throws java.lang.Exception
Description copied from class:ByteToMessageDecoder
Gets called after theByteToMessageDecoder
was removed from the actual context and it doesn't handle events anymore.- Overrides:
handlerRemoved0
in classByteToMessageDecoder
- Throws:
java.lang.Exception
-
bind
public void bind(ChannelHandlerContext ctx, java.net.SocketAddress localAddress, ChannelPromise promise) throws java.lang.Exception
Description copied from interface:ChannelOutboundHandler
Called once a bind operation is made.- Specified by:
bind
in interfaceChannelOutboundHandler
- Parameters:
ctx
- theChannelHandlerContext
for which the bind operation is madelocalAddress
- theSocketAddress
to which it should boundpromise
- theChannelPromise
to notify once the operation completes- Throws:
java.lang.Exception
- thrown if an error occurs
-
connect
public void connect(ChannelHandlerContext ctx, java.net.SocketAddress remoteAddress, java.net.SocketAddress localAddress, ChannelPromise promise) throws java.lang.Exception
Description copied from interface:ChannelOutboundHandler
Called once a connect operation is made.- Specified by:
connect
in interfaceChannelOutboundHandler
- Parameters:
ctx
- theChannelHandlerContext
for which the connect operation is maderemoteAddress
- theSocketAddress
to which it should connectlocalAddress
- theSocketAddress
which is used as source on connectpromise
- theChannelPromise
to notify once the operation completes- Throws:
java.lang.Exception
- thrown if an error occurs
-
deregister
public void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws java.lang.Exception
Description copied from interface:ChannelOutboundHandler
Called once a deregister operation is made from the current registeredEventLoop
.- Specified by:
deregister
in interfaceChannelOutboundHandler
- Parameters:
ctx
- theChannelHandlerContext
for which the close operation is madepromise
- theChannelPromise
to notify once the operation completes- Throws:
java.lang.Exception
- thrown if an error occurs
-
disconnect
public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) throws java.lang.Exception
Description copied from interface:ChannelOutboundHandler
Called once a disconnect operation is made.- Specified by:
disconnect
in interfaceChannelOutboundHandler
- Parameters:
ctx
- theChannelHandlerContext
for which the disconnect operation is madepromise
- theChannelPromise
to notify once the operation completes- Throws:
java.lang.Exception
- thrown if an error occurs
-
close
public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws java.lang.Exception
Description copied from interface:ChannelOutboundHandler
Called once a close operation is made.- Specified by:
close
in interfaceChannelOutboundHandler
- Parameters:
ctx
- theChannelHandlerContext
for which the close operation is madepromise
- theChannelPromise
to notify once the operation completes- Throws:
java.lang.Exception
- thrown if an error occurs
-
read
public void read(ChannelHandlerContext ctx) throws java.lang.Exception
Description copied from interface:ChannelOutboundHandler
InterceptsChannelHandlerContext.read()
.- Specified by:
read
in interfaceChannelOutboundHandler
- Throws:
java.lang.Exception
-
newPendingWritesNullException
private static java.lang.IllegalStateException newPendingWritesNullException()
-
write
public void write(ChannelHandlerContext ctx, java.lang.Object msg, ChannelPromise promise) throws java.lang.Exception
Description copied from interface:ChannelOutboundHandler
Called once a write operation is made. The write operation will write the messages through theChannelPipeline
. Those are then ready to be flushed to the actualChannel
onceChannel.flush()
is called- Specified by:
write
in interfaceChannelOutboundHandler
- Parameters:
ctx
- theChannelHandlerContext
for which the write operation is mademsg
- the message to writepromise
- theChannelPromise
to notify once the operation completes- Throws:
java.lang.Exception
- thrown if an error occurs
-
flush
public void flush(ChannelHandlerContext ctx) throws java.lang.Exception
Description copied from interface:ChannelOutboundHandler
Called once a flush operation is made. The flush operation will try to flush out all previous written messages that are pending.- Specified by:
flush
in interfaceChannelOutboundHandler
- Parameters:
ctx
- theChannelHandlerContext
for which the flush operation is made- Throws:
java.lang.Exception
- thrown if an error occurs
-
wrapAndFlush
private void wrapAndFlush(ChannelHandlerContext ctx) throws javax.net.ssl.SSLException
- Throws:
javax.net.ssl.SSLException
-
wrap
private void wrap(ChannelHandlerContext ctx, boolean inUnwrap) throws javax.net.ssl.SSLException
- Throws:
javax.net.ssl.SSLException
-
finishWrap
private void finishWrap(ChannelHandlerContext ctx, ByteBuf out, ChannelPromise promise, boolean inUnwrap, boolean needUnwrap)
-
wrapNonAppData
private boolean wrapNonAppData(ChannelHandlerContext ctx, boolean inUnwrap) throws javax.net.ssl.SSLException
This method will not callsetHandshakeFailure(ChannelHandlerContext, Throwable, boolean, boolean, boolean)
orsetHandshakeFailure(ChannelHandlerContext, Throwable)
.- Returns:
true
if this method ends onSSLEngineResult.HandshakeStatus.NOT_HANDSHAKING
.- Throws:
javax.net.ssl.SSLException
-
wrap
private javax.net.ssl.SSLEngineResult wrap(ByteBufAllocator alloc, javax.net.ssl.SSLEngine engine, ByteBuf in, ByteBuf out) throws javax.net.ssl.SSLException
- Throws:
javax.net.ssl.SSLException
-
channelInactive
public void channelInactive(ChannelHandlerContext ctx) throws java.lang.Exception
Description copied from class:ChannelInboundHandlerAdapter
CallsChannelHandlerContext.fireChannelInactive()
to forward to the nextChannelInboundHandler
in theChannelPipeline
. Sub-classes may override this method to change behavior.- Specified by:
channelInactive
in interfaceChannelInboundHandler
- Overrides:
channelInactive
in classByteToMessageDecoder
- Throws:
java.lang.Exception
-
exceptionCaught
public void exceptionCaught(ChannelHandlerContext ctx, java.lang.Throwable cause) throws java.lang.Exception
Description copied from class:ChannelInboundHandlerAdapter
CallsChannelHandlerContext.fireExceptionCaught(Throwable)
to forward to the nextChannelHandler
in theChannelPipeline
. Sub-classes may override this method to change behavior.- Specified by:
exceptionCaught
in interfaceChannelHandler
- Specified by:
exceptionCaught
in interfaceChannelInboundHandler
- Overrides:
exceptionCaught
in classChannelInboundHandlerAdapter
- Throws:
java.lang.Exception
-
ignoreException
private boolean ignoreException(java.lang.Throwable t)
Checks if the givenThrowable
can be ignore and just "swallowed" When an ssl connection is closed a close_notify message is sent. After that the peer also sends close_notify however, it's not mandatory to receive the close_notify. The party who sent the initial close_notify can close the connection immediately then the peer will get connection reset error.
-
isEncrypted
public static boolean isEncrypted(ByteBuf buffer)
Returnstrue
if the givenByteBuf
is encrypted. Be aware that this method will not increase the readerIndex of the givenByteBuf
.- Parameters:
buffer
- TheByteBuf
to read from. Be aware that it must have at least 5 bytes to read, otherwise it will throw anIllegalArgumentException
.- Returns:
- encrypted
true
if theByteBuf
is encrypted,false
otherwise. - Throws:
java.lang.IllegalArgumentException
- Is thrown if the givenByteBuf
has not at least 5 bytes to read.
-
decodeJdkCompatible
private void decodeJdkCompatible(ChannelHandlerContext ctx, ByteBuf in) throws NotSslRecordException
- Throws:
NotSslRecordException
-
decodeNonJdkCompatible
private void decodeNonJdkCompatible(ChannelHandlerContext ctx, ByteBuf in)
-
handleUnwrapThrowable
private void handleUnwrapThrowable(ChannelHandlerContext ctx, java.lang.Throwable cause)
-
decode
protected void decode(ChannelHandlerContext ctx, ByteBuf in, java.util.List<java.lang.Object> out) throws javax.net.ssl.SSLException
Description copied from class:ByteToMessageDecoder
Decode the from oneByteBuf
to an other. This method will be called till either the inputByteBuf
has nothing to read when return from this method or till nothing was read from the inputByteBuf
.- Specified by:
decode
in classByteToMessageDecoder
- Parameters:
ctx
- theChannelHandlerContext
which thisByteToMessageDecoder
belongs toin
- theByteBuf
from which to read dataout
- theList
to which decoded messages should be added- Throws:
javax.net.ssl.SSLException
-
channelReadComplete
public void channelReadComplete(ChannelHandlerContext ctx) throws java.lang.Exception
Description copied from class:ChannelInboundHandlerAdapter
CallsChannelHandlerContext.fireChannelReadComplete()
to forward to the nextChannelInboundHandler
in theChannelPipeline
. Sub-classes may override this method to change behavior.- Specified by:
channelReadComplete
in interfaceChannelInboundHandler
- Overrides:
channelReadComplete
in classByteToMessageDecoder
- Throws:
java.lang.Exception
-
channelReadComplete0
private void channelReadComplete0(ChannelHandlerContext ctx)
-
readIfNeeded
private void readIfNeeded(ChannelHandlerContext ctx)
-
flushIfNeeded
private void flushIfNeeded(ChannelHandlerContext ctx)
-
unwrapNonAppData
private void unwrapNonAppData(ChannelHandlerContext ctx) throws javax.net.ssl.SSLException
CallsSSLEngine.unwrap(ByteBuffer, ByteBuffer)
with an empty buffer to handle handshakes, etc.- Throws:
javax.net.ssl.SSLException
-
unwrap
private int unwrap(ChannelHandlerContext ctx, ByteBuf packet, int offset, int length) throws javax.net.ssl.SSLException
Unwraps inbound SSL records.- Throws:
javax.net.ssl.SSLException
-
toByteBuffer
private static java.nio.ByteBuffer toByteBuffer(ByteBuf out, int index, int len)
-
inEventLoop
private static boolean inEventLoop(java.util.concurrent.Executor executor)
-
runAllDelegatedTasks
private static void runAllDelegatedTasks(javax.net.ssl.SSLEngine engine)
-
runDelegatedTasks
private boolean runDelegatedTasks(boolean inUnwrap)
Will either run the delegated task directly callingRunnable.run()
and returntrue
or will offload the delegated task usingExecutor.execute(Runnable)
and returnfalse
. If the task is offloaded it will take care to resume its work on theEventExecutor
once there are no more tasks to process.
-
executeDelegatedTasks
private void executeDelegatedTasks(boolean inUnwrap)
-
setHandshakeSuccessIfStillHandshaking
private boolean setHandshakeSuccessIfStillHandshaking()
Works around some AndroidSSLEngine
implementations that skipSSLEngineResult.HandshakeStatus.FINISHED
and go straight intoSSLEngineResult.HandshakeStatus.NOT_HANDSHAKING
when handshake is finished.- Returns:
true
if and only if the workaround has been applied and thushandshakeFuture()
has been marked as success by this method
-
setHandshakeSuccess
private void setHandshakeSuccess()
Notify all the handshake futures about the successfully handshake
-
setHandshakeFailure
private void setHandshakeFailure(ChannelHandlerContext ctx, java.lang.Throwable cause)
Notify all the handshake futures about the failure during the handshake.
-
setHandshakeFailure
private void setHandshakeFailure(ChannelHandlerContext ctx, java.lang.Throwable cause, boolean closeInbound, boolean notify, boolean alwaysFlushAndClose)
Notify all the handshake futures about the failure during the handshake.
-
setHandshakeFailureTransportFailure
private void setHandshakeFailureTransportFailure(ChannelHandlerContext ctx, java.lang.Throwable cause)
-
releaseAndFailAll
private void releaseAndFailAll(ChannelHandlerContext ctx, java.lang.Throwable cause)
-
notifyClosePromise
private void notifyClosePromise(java.lang.Throwable cause)
-
closeOutboundAndChannel
private void closeOutboundAndChannel(ChannelHandlerContext ctx, ChannelPromise promise, boolean disconnect) throws java.lang.Exception
- Throws:
java.lang.Exception
-
flush
private void flush(ChannelHandlerContext ctx, ChannelPromise promise) throws java.lang.Exception
- Throws:
java.lang.Exception
-
handlerAdded
public void handlerAdded(ChannelHandlerContext ctx) throws java.lang.Exception
Description copied from class:ChannelHandlerAdapter
Do nothing by default, sub-classes may override this method.- Specified by:
handlerAdded
in interfaceChannelHandler
- Overrides:
handlerAdded
in classChannelHandlerAdapter
- Throws:
java.lang.Exception
-
startHandshakeProcessing
private void startHandshakeProcessing()
-
renegotiate
public Future<Channel> renegotiate(Promise<Channel> promise)
Performs TLS renegotiation.
-
handshake
private void handshake()
Performs TLS (re)negotiation.
-
applyHandshakeTimeout
private void applyHandshakeTimeout()
-
forceFlush
private void forceFlush(ChannelHandlerContext ctx)
-
channelActive
public void channelActive(ChannelHandlerContext ctx) throws java.lang.Exception
Issues an initial TLS handshake once connected when used in client-mode- Specified by:
channelActive
in interfaceChannelInboundHandler
- Overrides:
channelActive
in classChannelInboundHandlerAdapter
- Throws:
java.lang.Exception
-
safeClose
private void safeClose(ChannelHandlerContext ctx, ChannelFuture flushFuture, ChannelPromise promise)
-
addCloseListener
private static void addCloseListener(ChannelFuture future, ChannelPromise promise)
-
allocate
private ByteBuf allocate(ChannelHandlerContext ctx, int capacity)
Always prefer a direct buffer when it's pooled, so that we reduce the number of memory copies inOpenSslEngine
.
-
allocateOutNetBuf
private ByteBuf allocateOutNetBuf(ChannelHandlerContext ctx, int pendingBytes, int numComponents)
Allocates an outbound network buffer forSSLEngine.wrap(ByteBuffer, ByteBuffer)
which can encrypt the specified amount of pending bytes.
-
-