Class SslHandler

All Implemented Interfaces:
ChannelHandler, ChannelInboundHandler, ChannelOutboundHandler

public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundHandler
Adds SSL · TLS and StartTLS support to a Channel. 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 the ChannelInboundHandler.userEventTriggered(ChannelHandlerContext, Object) method and check for a SslHandshakeCompletionEvent.

Handshake

The handshake will be automatically issued for you once the Channel is active and SSLEngine.getUseClientMode() returns true. 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 the close_notify message to the remote peer. One exception is when you close the Channel - SslHandler intercepts the close request and send the close_notify message before the channel closure automatically. Once the SSL session is closed, it is not reusable, and consequently you should create a new SslHandler with a new SSLEngine as explained in the following section.

Restarting the session

To restart the SSL session, you must remove the existing closed SslHandler from the ChannelPipeline, insert a new SslHandler with a new SSLEngine 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:

  1. Client sends a StartTLS request to server.
  2. Server sends a StartTLS response to client.
  3. Client begins SSL handshake.
If you implement a server, you need to:
  1. create a new SslHandler instance with startTls flag set to true,
  2. insert the SslHandler to the ChannelPipeline, and
  3. write a StartTLS response.
Please note that you must insert SslHandler before sending the StartTLS response. Otherwise the client can send begin SSL handshake before SslHandler is inserted to the ChannelPipeline, causing data corruption.

The client-side implementation is much simpler.

  1. Write a StartTLS request,
  2. wait for the StartTLS response,
  3. create a new SslHandler instance with startTls flag set to false,
  4. insert the SslHandler to the ChannelPipeline, and
  5. 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.

  • Field Details

    • logger

      private static final InternalLogger logger
    • IGNORABLE_ERROR_MESSAGE

      private static final java.util.regex.Pattern IGNORABLE_ERROR_MESSAGE
    • STATE_SENT_FIRST_MESSAGE

      private static final int STATE_SENT_FIRST_MESSAGE
      See Also:
    • STATE_FLUSHED_BEFORE_HANDSHAKE

      private static final int STATE_FLUSHED_BEFORE_HANDSHAKE
      See Also:
    • STATE_READ_DURING_HANDSHAKE

      private static final int STATE_READ_DURING_HANDSHAKE
      See Also:
    • STATE_HANDSHAKE_STARTED

      private static final int STATE_HANDSHAKE_STARTED
      See Also:
    • STATE_NEEDS_FLUSH

      private static final int STATE_NEEDS_FLUSH
      Set by wrap*() methods when something is produced. channelReadComplete(ChannelHandlerContext) will check this flag, clear it, and call ctx.flush().
      See Also:
    • STATE_OUTBOUND_CLOSED

      private static final int STATE_OUTBOUND_CLOSED
      See Also:
    • STATE_CLOSE_NOTIFY

      private static final int STATE_CLOSE_NOTIFY
      See Also:
    • STATE_PROCESS_TASK

      private static final int STATE_PROCESS_TASK
      See Also:
    • STATE_FIRE_CHANNEL_READ

      private static final int STATE_FIRE_CHANNEL_READ
      This flag is used to determine if we need to call ChannelHandlerContext.read() to consume more data when ChannelConfig.isAutoRead() is false.
      See Also:
    • STATE_UNWRAP_REENTRY

      private static final int STATE_UNWRAP_REENTRY
      See Also:
    • 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:
    • JDK_MIN_UNWRAP_OVERHEAD

      private static final int JDK_MIN_UNWRAP_OVERHEAD
      The JDK SSLEngine wants at least packetLength - 5 - 16 bytes to unwrap a record, as it subtracts the 5 byte header and at least 16 bytes of tag or MAC for every cipher suite.

      The BUFFER_OVERFLOW check calls estimateFragmentSize(packetLen): https://github.com/openjdk/jdk/blob/6917797/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java#L672 which for AEAD ciphers subtracts the header and tag size from the packet length: https://github.com/openjdk/jdk/blob/6917797/src/java.base/share/classes/sun/security/ssl/SSLCipher.java#L1969

      See Also:
    • 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 if SSLEngine.wrap(ByteBuffer[], ByteBuffer) and SSLEngine.unwrap(ByteBuffer, ByteBuffer[]) should be called with a ByteBuf that is only backed by one ByteBuffer to reduce the object creation.
    • unwrapInputCopy

      private java.nio.ByteBuffer unwrapInputCopy
    • startTls

      private final boolean startTls
    • resumptionController

      private final ResumptionController resumptionController
    • sslTaskRunnerForUnwrap

      private final SslHandler.SslTasksRunner sslTaskRunnerForUnwrap
    • sslTaskRunner

      private final SslHandler.SslTasksRunner sslTaskRunner
    • pendingUnencryptedWrites

      private SslHandlerCoalescingBufferQueue pendingUnencryptedWrites
    • handshakePromise

      private Promise<Channel> handshakePromise
    • sslClosePromise

      private final SslHandler.LazyChannelPromise sslClosePromise
    • packetLength

      private int packetLength
    • state

      private short state
    • handshakeTimeoutMillis

      private volatile long handshakeTimeoutMillis
    • closeNotifyFlushTimeoutMillis

      private volatile long closeNotifyFlushTimeoutMillis
    • closeNotifyReadTimeoutMillis

      private volatile long closeNotifyReadTimeoutMillis
    • wrapDataSize

      volatile int wrapDataSize
  • Constructor Details

    • SslHandler

      public SslHandler(javax.net.ssl.SSLEngine engine)
      Creates a new instance which runs all delegated tasks directly on the EventExecutor.
      Parameters:
      engine - the SSLEngine 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 the EventExecutor.
      Parameters:
      engine - the SSLEngine this handler will use
      startTls - true if the first write request shouldn't be encrypted by the SSLEngine
    • SslHandler

      public SslHandler(javax.net.ssl.SSLEngine engine, java.util.concurrent.Executor delegatedTaskExecutor)
      Creates a new instance.
      Parameters:
      engine - the SSLEngine this handler will use
      delegatedTaskExecutor - the Executor that will be used to execute tasks that are returned by SSLEngine.getDelegatedTask().
    • SslHandler

      public SslHandler(javax.net.ssl.SSLEngine engine, boolean startTls, java.util.concurrent.Executor delegatedTaskExecutor)
      Creates a new instance.
      Parameters:
      engine - the SSLEngine this handler will use
      startTls - true if the first write request shouldn't be encrypted by the SSLEngine
      delegatedTaskExecutor - the Executor that will be used to execute tasks that are returned by SSLEngine.getDelegatedTask().
    • SslHandler

      SslHandler(javax.net.ssl.SSLEngine engine, boolean startTls, java.util.concurrent.Executor delegatedTaskExecutor, ResumptionController resumptionController)
  • Method Details

    • 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 each SSLEngine.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 if wrapDataSize <= data size then we will divide the data into chunks of wrapDataSize 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 each SSLEngine.wrap(ByteBuffer[], int, int, ByteBuffer) call.
    • getCloseNotifyTimeoutMillis

      @Deprecated public long getCloseNotifyTimeoutMillis()
    • setCloseNotifyTimeout

      @Deprecated public void setCloseNotifyTimeout(long closeNotifyTimeout, java.util.concurrent.TimeUnit unit)
    • setCloseNotifyTimeoutMillis

      @Deprecated public void setCloseNotifyTimeoutMillis(long closeNotifyFlushTimeoutMillis)
    • getCloseNotifyFlushTimeoutMillis

      public final long getCloseNotifyFlushTimeoutMillis()
      Gets the timeout for flushing the close_notify that was triggered by closing the Channel. If the close_notify was not flushed in the given timeout the Channel will be closed forcibly.
    • setCloseNotifyFlushTimeout

      public final void setCloseNotifyFlushTimeout(long closeNotifyFlushTimeout, java.util.concurrent.TimeUnit unit)
      Sets the timeout for flushing the close_notify that was triggered by closing the Channel. If the close_notify was not flushed in the given timeout the Channel will be closed forcibly.
    • setCloseNotifyFlushTimeoutMillis

      public final void setCloseNotifyFlushTimeoutMillis(long closeNotifyFlushTimeoutMillis)
    • getCloseNotifyReadTimeoutMillis

      public final long getCloseNotifyReadTimeoutMillis()
      Gets the timeout (in ms) for receiving the response for the close_notify that was triggered by closing the Channel. This timeout starts after the close_notify message was successfully written to the remote peer. Use 0 to directly close the Channel and not wait for the response.
    • setCloseNotifyReadTimeout

      public final 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 the Channel. This timeout starts after the close_notify message was successfully written to the remote peer. Use 0 to directly close the Channel and not wait for the response.
    • setCloseNotifyReadTimeoutMillis

      public final void setCloseNotifyReadTimeoutMillis(long closeNotifyReadTimeoutMillis)
    • engine

      public javax.net.ssl.SSLEngine engine()
      Returns the SSLEngine 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 a Future that will get notified once the current TLS handshake completes.
      Returns:
      the Future for the initial TLS handshake if renegotiate() was not invoked. The Future for the most recent TLS renegotiation otherwise.
    • close

      @Deprecated public ChannelFuture close()
      Deprecated.
    • close

      @Deprecated public ChannelFuture close(ChannelPromise promise)
      Deprecated.
    • closeOutbound

      public ChannelFuture closeOutbound()
      Sends an SSL close_notify message to the specified channel and destroys the underlying SSLEngine. This will not close the underlying Channel. If you want to also close the Channel use Channel.close() or ChannelOutboundInvoker.close()
    • closeOutbound

      public ChannelFuture closeOutbound(ChannelPromise promise)
      Sends an SSL close_notify message to the specified channel and destroys the underlying SSLEngine. This will not close the underlying Channel. If you want to also close the Channel use Channel.close() or ChannelOutboundInvoker.close()
    • closeOutbound0

      private void closeOutbound0(ChannelPromise promise)
    • sslCloseFuture

      public Future<Channel> sslCloseFuture()
      Return the Future that will get notified if the inbound of the SSLEngine is closed. This method will return the same Future all the time.
      See Also:
      • SSLEngine
    • handlerRemoved0

      public void handlerRemoved0(ChannelHandlerContext ctx) throws java.lang.Exception
      Description copied from class: ByteToMessageDecoder
      Gets called after the ByteToMessageDecoder was removed from the actual context and it doesn't handle events anymore.
      Overrides:
      handlerRemoved0 in class ByteToMessageDecoder
      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 interface ChannelOutboundHandler
      Parameters:
      ctx - the ChannelHandlerContext for which the bind operation is made
      localAddress - the SocketAddress to which it should bound
      promise - the ChannelPromise 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 interface ChannelOutboundHandler
      Parameters:
      ctx - the ChannelHandlerContext for which the connect operation is made
      remoteAddress - the SocketAddress to which it should connect
      localAddress - the SocketAddress which is used as source on connect
      promise - the ChannelPromise 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 registered EventLoop.
      Specified by:
      deregister in interface ChannelOutboundHandler
      Parameters:
      ctx - the ChannelHandlerContext for which the close operation is made
      promise - the ChannelPromise 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 interface ChannelOutboundHandler
      Parameters:
      ctx - the ChannelHandlerContext for which the disconnect operation is made
      promise - the ChannelPromise 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 interface ChannelOutboundHandler
      Parameters:
      ctx - the ChannelHandlerContext for which the close operation is made
      promise - the ChannelPromise 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
      Specified by:
      read in interface ChannelOutboundHandler
      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 the ChannelPipeline. Those are then ready to be flushed to the actual Channel once Channel.flush() is called
      Specified by:
      write in interface ChannelOutboundHandler
      Parameters:
      ctx - the ChannelHandlerContext for which the write operation is made
      msg - the message to write
      promise - the ChannelPromise 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 interface ChannelOutboundHandler
      Parameters:
      ctx - the ChannelHandlerContext 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
    • wrapNonAppData

      private boolean wrapNonAppData(ChannelHandlerContext ctx, boolean inUnwrap) throws javax.net.ssl.SSLException
      Returns:
      true if this method ends on SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING.
      Throws:
      javax.net.ssl.SSLException
    • wrapMultiple

      private javax.net.ssl.SSLEngineResult wrapMultiple(ByteBufAllocator alloc, javax.net.ssl.SSLEngine engine, ByteBuf in, ByteBuf out) throws javax.net.ssl.SSLException
      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
      Calls ChannelHandlerContext.fireChannelInactive() to forward to the next ChannelInboundHandler in the ChannelPipeline. Sub-classes may override this method to change behavior.
      Specified by:
      channelInactive in interface ChannelInboundHandler
      Overrides:
      channelInactive in class ByteToMessageDecoder
      Throws:
      java.lang.Exception
    • exceptionCaught

      public void exceptionCaught(ChannelHandlerContext ctx, java.lang.Throwable cause) throws java.lang.Exception
      Description copied from class: ChannelInboundHandlerAdapter
      Calls ChannelHandlerContext.fireExceptionCaught(Throwable) to forward to the next ChannelHandler in the ChannelPipeline. Sub-classes may override this method to change behavior.
      Specified by:
      exceptionCaught in interface ChannelHandler
      Specified by:
      exceptionCaught in interface ChannelInboundHandler
      Overrides:
      exceptionCaught in class ChannelInboundHandlerAdapter
      Throws:
      java.lang.Exception
    • ignoreException

      private boolean ignoreException(java.lang.Throwable t)
      Checks if the given Throwable 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.
    • isIgnorableClassInStack

      private static boolean isIgnorableClassInStack(java.lang.String classname)
    • isEncrypted

      @Deprecated public static boolean isEncrypted(ByteBuf buffer)
      Returns true if the given ByteBuf is encrypted. Be aware that this method will not increase the readerIndex of the given ByteBuf.
      Parameters:
      buffer - The ByteBuf to read from. Be aware that it must have at least 5 bytes to read, otherwise it will throw an IllegalArgumentException.
      Returns:
      encrypted true if the ByteBuf is encrypted, false otherwise.
      Throws:
      java.lang.IllegalArgumentException - Is thrown if the given ByteBuf has not at least 5 bytes to read.
    • isEncrypted

      public static boolean isEncrypted(ByteBuf buffer, boolean probeSSLv2)
      Returns true if the given ByteBuf is encrypted. Be aware that this method will not increase the readerIndex of the given ByteBuf.
      Parameters:
      buffer - The ByteBuf to read from. Be aware that it must have at least 5 bytes to read, otherwise it will throw an IllegalArgumentException.
      probeSSLv2 - true if the input buffer might be SSLv2. If true is used this methods might produce false-positives in some cases so it's strongly suggested to use false.
      Returns:
      encrypted true if the ByteBuf is encrypted, false otherwise.
      Throws:
      java.lang.IllegalArgumentException - Is thrown if the given ByteBuf 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 one ByteBuf to an other. This method will be called till either the input ByteBuf has nothing to read when return from this method or till nothing was read from the input ByteBuf.
      Specified by:
      decode in class ByteToMessageDecoder
      Parameters:
      ctx - the ChannelHandlerContext which this ByteToMessageDecoder belongs to
      in - the ByteBuf from which to read data
      out - the List 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
      Calls ChannelHandlerContext.fireChannelReadComplete() to forward to the next ChannelInboundHandler in the ChannelPipeline. Sub-classes may override this method to change behavior.
      Specified by:
      channelReadComplete in interface ChannelInboundHandler
      Overrides:
      channelReadComplete in class ByteToMessageDecoder
      Throws:
      java.lang.Exception
    • channelReadComplete0

      private void channelReadComplete0(ChannelHandlerContext ctx)
    • readIfNeeded

      private void readIfNeeded(ChannelHandlerContext ctx)
    • flushIfNeeded

      private void flushIfNeeded(ChannelHandlerContext ctx)
    • unwrapNonAppData

      private int unwrapNonAppData(ChannelHandlerContext ctx) throws javax.net.ssl.SSLException
      Calls SSLEngine.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 length) throws javax.net.ssl.SSLException
      Unwraps inbound SSL records.
      Throws:
      javax.net.ssl.SSLException
    • setHandshakeSuccessUnwrapMarkReentry

      private boolean setHandshakeSuccessUnwrapMarkReentry() throws javax.net.ssl.SSLException
      Throws:
      javax.net.ssl.SSLException
    • executeNotifyClosePromise

      private void executeNotifyClosePromise(ChannelHandlerContext ctx)
    • executeChannelRead

      private void executeChannelRead(ChannelHandlerContext ctx, ByteBuf decodedOut)
    • toByteBuffer

      private static java.nio.ByteBuffer toByteBuffer(ByteBuf out, int index, int len)
    • inEventLoop

      private static boolean inEventLoop(java.util.concurrent.Executor executor)
    • runDelegatedTasks

      private boolean runDelegatedTasks(boolean inUnwrap)
      Will either run the delegated task directly calling Runnable.run() and return true or will offload the delegated task using Executor.execute(Runnable) and return false. If the task is offloaded it will take care to resume its work on the EventExecutor once there are no more tasks to process.
    • getTaskRunner

      private SslHandler.SslTasksRunner getTaskRunner(boolean inUnwrap)
    • executeDelegatedTask

      private void executeDelegatedTask(boolean inUnwrap)
    • executeDelegatedTask

      private void executeDelegatedTask(SslHandler.SslTasksRunner task)
    • setHandshakeSuccess

      private boolean setHandshakeSuccess() throws javax.net.ssl.SSLException
      Notify all the handshake futures about the successfully handshake
      Returns:
      true if handshakePromise was set successfully and a SslHandshakeCompletionEvent was fired. false otherwise.
      Throws:
      javax.net.ssl.SSLException
    • 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 interface ChannelHandler
      Overrides:
      handlerAdded in class ChannelHandlerAdapter
      Throws:
      java.lang.Exception
    • startHandshakeProcessing

      private void startHandshakeProcessing(boolean flushAtEnd)
    • renegotiate

      public Future<Channel> renegotiate()
      Performs TLS renegotiation.
    • renegotiate

      public Future<Channel> renegotiate(Promise<Channel> promise)
      Performs TLS renegotiation.
    • renegotiateOnEventLoop

      private void renegotiateOnEventLoop(Promise<Channel> newHandshakePromise)
    • handshake

      private void handshake(boolean flushAtEnd)
      Performs TLS (re)negotiation.
      Parameters:
      flushAtEnd - Set to true if the outbound buffer should be flushed (written to the network) at the end. Set to false if the handshake will be flushed later, e.g. as part of TCP Fast Open connect.
    • applyHandshakeTimeout

      private void applyHandshakeTimeout()
    • forceFlush

      private void forceFlush(ChannelHandlerContext ctx)
    • setOpensslEngineSocketFd

      private void setOpensslEngineSocketFd(Channel c)
    • 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 interface ChannelInboundHandler
      Overrides:
      channelActive in class ChannelInboundHandlerAdapter
      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 in OpenSslEngine.
    • allocateOutNetBuf

      private ByteBuf allocateOutNetBuf(ChannelHandlerContext ctx, int pendingBytes, int numComponents)
      Allocates an outbound network buffer for SSLEngine.wrap(ByteBuffer, ByteBuffer) which can encrypt the specified amount of pending bytes.
    • isStateSet

      private boolean isStateSet(int bit)
    • setState

      private void setState(int bit)
    • clearState

      private void clearState(int bit)