Class SslConnection

java.lang.Object
org.eclipse.jetty.io.AbstractConnection
org.eclipse.jetty.io.ssl.SslConnection
All Implemented Interfaces:
Closeable, AutoCloseable, Connection, Connection.UpgradeTo

public class SslConnection extends AbstractConnection implements Connection.UpgradeTo
A Connection that acts as an interceptor between an EndPoint providing SSL encrypted data and another consumer of an EndPoint (typically an Connection like HttpConnection) that wants unencrypted data.

The connector uses an EndPoint (typically SocketChannelEndPoint) as it's source/sink of encrypted data. It then provides an endpoint via getDecryptedEndPoint() to expose a source/sink of unencrypted data to another connection (eg HttpConnection).

The design of this class is based on a clear separation between the passive methods, which do not block nor schedule any asynchronous callbacks, and active methods that do schedule asynchronous callbacks.

The passive methods are SslConnection.DecryptedEndPoint.fill(ByteBuffer) and SslConnection.DecryptedEndPoint.flush(ByteBuffer...). They make best effort attempts to progress the connection using only calls to the encrypted EndPoint.fill(ByteBuffer) and EndPoint.flush(ByteBuffer...) methods. They will never block nor schedule any readInterest or write callbacks. If a fill/flush cannot progress either because of network congestion or waiting for an SSL handshake message, then the fill/flush will simply return with zero bytes filled/flushed. Specifically, if a flush cannot proceed because it needs to receive a handshake message, then the flush will attempt to fill bytes from the encrypted endpoint, but if insufficient bytes are read it will NOT call EndPoint.fillInterested(Callback).

It is only the active methods : AbstractEndPoint.fillInterested(Callback) and AbstractEndPoint.write(Callback, ByteBuffer...) that may schedule callbacks by calling the encrypted EndPoint.fillInterested(Callback) and EndPoint.write(Callback, ByteBuffer...) methods. For normal data handling, the decrypted fillInterest method will result in an encrypted fillInterest and a decrypted write will result in an encrypted write. However, due to SSL handshaking requirements, it is also possible for a decrypted fill to call the encrypted write and for the decrypted flush to call the encrypted fillInterested methods.

MOST IMPORTANTLY, the encrypted callbacks from the active methods (#onFillable() and WriteFlusher#completeWrite()) do no filling or flushing themselves. Instead they simple make the callbacks to the decrypted callbacks, so that the passive encrypted fill/flush will be called again and make another best effort attempt to progress the connection.

  • Field Details

    • LOG

      private static final Logger LOG
    • TLS_1_3

      private static final String TLS_1_3
      See Also:
    • handshakeListeners

      private final List<SslHandshakeListener> handshakeListeners
    • _bufferPool

      private final ByteBufferPool _bufferPool
    • _sslEngine

      private final SSLEngine _sslEngine
    • _decryptedEndPoint

      private final SslConnection.DecryptedEndPoint _decryptedEndPoint
    • _decryptedInput

      private ByteBuffer _decryptedInput
    • _encryptedInput

      private ByteBuffer _encryptedInput
    • _encryptedOutput

      private ByteBuffer _encryptedOutput
    • _encryptedDirectBuffers

      private final boolean _encryptedDirectBuffers
    • _decryptedDirectBuffers

      private final boolean _decryptedDirectBuffers
    • _renegotiationAllowed

      private boolean _renegotiationAllowed
    • _renegotiationLimit

      private int _renegotiationLimit
    • _closedOutbound

      private boolean _closedOutbound
    • _requireCloseMessage

      private boolean _requireCloseMessage
    • _flushState

      private SslConnection.FlushState _flushState
    • _fillState

      private SslConnection.FillState _fillState
    • _handshake

    • _underflown

      private boolean _underflown
    • _runFillable

      private final Runnable _runFillable
    • _sslReadCallback

      private final Callback _sslReadCallback
  • Constructor Details

  • Method Details

    • addHandshakeListener

      public void addHandshakeListener(SslHandshakeListener listener)
    • removeHandshakeListener

      public boolean removeHandshakeListener(SslHandshakeListener listener)
    • newDecryptedEndPoint

      protected SslConnection.DecryptedEndPoint newDecryptedEndPoint()
    • getSSLEngine

      public SSLEngine getSSLEngine()
    • getDecryptedEndPoint

      public SslConnection.DecryptedEndPoint getDecryptedEndPoint()
    • isRenegotiationAllowed

      public boolean isRenegotiationAllowed()
    • setRenegotiationAllowed

      public void setRenegotiationAllowed(boolean renegotiationAllowed)
    • getRenegotiationLimit

      public int getRenegotiationLimit()
      Returns:
      The number of renegotiations allowed for this connection. When the limit is 0 renegotiation will be denied. If the limit is less than 0 then no limit is applied.
    • setRenegotiationLimit

      public void setRenegotiationLimit(int renegotiationLimit)
      Parameters:
      renegotiationLimit - The number of renegotiations allowed for this connection. When the limit is 0 renegotiation will be denied. If the limit is less than 0 then no limit is applied. Default -1.
    • isAllowMissingCloseMessage

      @Deprecated public boolean isAllowMissingCloseMessage()
      Deprecated.
      use inverted isRequireCloseMessage() instead
      Returns:
      whether is not required that peers send the TLS close_notify message
    • setAllowMissingCloseMessage

      @Deprecated public void setAllowMissingCloseMessage(boolean allowMissingCloseMessage)
      Deprecated.
      use inverted setRequireCloseMessage(boolean) instead
      Parameters:
      allowMissingCloseMessage - whether is not required that peers send the TLS close_notify message
    • isRequireCloseMessage

      public boolean isRequireCloseMessage()
      Returns:
      whether peers must send the TLS close_notify message
    • setRequireCloseMessage

      public void setRequireCloseMessage(boolean requireCloseMessage)

      Sets whether it is required that a peer send the TLS close_notify message to indicate the will to close the connection, otherwise it may be interpreted as a truncation attack.

      This option is only useful on clients, since typically servers cannot accept connection-delimited content that may be truncated.

      Parameters:
      requireCloseMessage - whether peers must send the TLS close_notify message
    • isHandshakeInitial

      private boolean isHandshakeInitial()
    • isHandshakeSucceeded

      private boolean isHandshakeSucceeded()
    • isHandshakeComplete

      private boolean isHandshakeComplete()
    • getApplicationBufferSize

      private int getApplicationBufferSize()
    • getPacketBufferSize

      private int getPacketBufferSize()
    • getBufferSize

      private int getBufferSize(ToIntFunction<SSLSession> bufferSizeFn)
    • acquireEncryptedInput

      private void acquireEncryptedInput()
    • acquireEncryptedOutput

      private void acquireEncryptedOutput()
    • onUpgradeTo

      public void onUpgradeTo(ByteBuffer buffer)
      Description copied from interface: Connection.UpgradeTo

      Invoked during an upgrade to receive a buffer containing bytes that have not been consumed by the upgrade-from connection, and that must be consumed by this connection.

      Specified by:
      onUpgradeTo in interface Connection.UpgradeTo
      Parameters:
      buffer - a non-null buffer of unconsumed bytes received from the upgrade-from connection. The buffer does not belong to any pool and should be discarded after having consumed its bytes.
    • onOpen

      public void onOpen()
      Description copied from interface: Connection

      Callback method invoked when this connection is opened.

      Creators of the connection implementation are responsible for calling this method.

      Specified by:
      onOpen in interface Connection
      Overrides:
      onOpen in class AbstractConnection
    • onClose

      public void onClose()
      Description copied from interface: Connection

      Callback method invoked when this connection is closed.

      Creators of the connection implementation are responsible for calling this method.

      Specified by:
      onClose in interface Connection
      Overrides:
      onClose in class AbstractConnection
    • close

      public void close()
      Description copied from interface: Connection

      Performs a logical close of this connection.

      For simple connections, this may just mean to delegate the close to the associated EndPoint but, for example, SSL connections should write the SSL close message before closing the associated EndPoint.

      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Specified by:
      close in interface Connection
      Overrides:
      close in class AbstractConnection
    • onIdleExpired

      public boolean onIdleExpired()
      Description copied from interface: Connection

      Callback method invoked upon an idle timeout event.

      Implementations of this method may return true to indicate that the idle timeout handling should proceed normally, typically failing the EndPoint and causing it to be closed.

      When false is returned, the handling of the idle timeout event is halted immediately and the EndPoint left in the state it was before the idle timeout event.

      Specified by:
      onIdleExpired in interface Connection
      Overrides:
      onIdleExpired in class AbstractConnection
      Returns:
      true to let the EndPoint handle the idle timeout, false to tell the EndPoint to halt the handling of the idle timeout.
    • onFillable

      public void onFillable()
      Description copied from class: AbstractConnection

      Callback method invoked when the endpoint is ready to be read.

      Specified by:
      onFillable in class AbstractConnection
      See Also:
    • onFillInterestedFailed

      public void onFillInterestedFailed(Throwable cause)
      Description copied from class: AbstractConnection

      Callback method invoked when the endpoint failed to be ready to be read.

      Overrides:
      onFillInterestedFailed in class AbstractConnection
      Parameters:
      cause - the exception that caused the failure
    • wrap

      protected SSLEngineResult wrap(SSLEngine sslEngine, ByteBuffer[] input, ByteBuffer output) throws SSLException
      Throws:
      SSLException
    • unwrap

      protected SSLEngineResult unwrap(SSLEngine sslEngine, ByteBuffer input, ByteBuffer output) throws SSLException
      Throws:
      SSLException
    • toConnectionString

      public String toConnectionString()
      Overrides:
      toConnectionString in class AbstractConnection
    • releaseEncryptedInputBuffer

      private void releaseEncryptedInputBuffer()
    • releaseDecryptedInputBuffer

      protected void releaseDecryptedInputBuffer()
    • releaseEncryptedOutputBuffer

      private void releaseEncryptedOutputBuffer()
    • networkFill

      protected int networkFill(ByteBuffer input) throws IOException
      Throws:
      IOException
    • networkFlush

      protected boolean networkFlush(ByteBuffer output) throws IOException
      Throws:
      IOException