Class UnifiedServerSocket.UnifiedSocket

  • All Implemented Interfaces:
    java.io.Closeable, java.lang.AutoCloseable
    Enclosing class:
    UnifiedServerSocket

    public static class UnifiedServerSocket.UnifiedSocket
    extends java.net.Socket
    The result of calling accept() on a UnifiedServerSocket. This is a Socket that doesn't know if it's using plaintext or SSL/TLS at the time when it is created. Calling a method that indicates a desire to read or write from the socket will cause the socket to detect if the connected client is attempting to establish a TLS or plaintext connection. This is done by doing a blocking read of 5 bytes off the socket and checking if the bytes look like the start of a TLS ClientHello message. If it looks like the client is attempting to connect with TLS, the internal socket is upgraded to a SSLSocket. If not, any bytes read from the socket are pushed back to the input stream, and the socket continues to be treated as a plaintext socket. The methods that trigger this behavior are: Calling other socket methods (i.e option setters such as Socket.setTcpNoDelay(boolean)) does not trigger mode detection. Because detecting the mode is a potentially blocking operation, it should not be done in the accepting thread. Attempting to read from or write to the socket in the accepting thread opens the caller up to a denial-of-service attack, in which a client connects and then does nothing. This would prevent any other clients from connecting. Passing the socket returned by accept() to a separate thread which handles all read and write operations protects against this DoS attack. Callers can check if the socket has been upgraded to TLS by calling isSecureSocket(), and can get the underlying SSLSocket by calling getSslSocket().
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void bind​(java.net.SocketAddress bindpoint)
      See Socket.bind(SocketAddress).
      void close()
      See Socket.close().
      void connect​(java.net.SocketAddress endpoint)
      See Socket.connect(SocketAddress).
      void connect​(java.net.SocketAddress endpoint, int timeout)
      See Socket.connect(SocketAddress, int).
      java.nio.channels.SocketChannel getChannel()
      See Socket.getChannel().
      java.net.InetAddress getInetAddress()
      See Socket.getInetAddress().
      java.io.InputStream getInputStream()
      See Socket.getInputStream().
      boolean getKeepAlive()
      See Socket.getKeepAlive().
      java.net.InetAddress getLocalAddress()
      See Socket.getLocalAddress().
      int getLocalPort()
      See Socket.getLocalPort().
      java.net.SocketAddress getLocalSocketAddress()
      See Socket.getLocalSocketAddress().
      boolean getOOBInline()
      See Socket.getOOBInline().
      java.io.OutputStream getOutputStream()
      See Socket.getOutputStream().
      int getPort()
      See Socket.getPort().
      int getReceiveBufferSize()
      See Socket.getReceiveBufferSize().
      java.net.SocketAddress getRemoteSocketAddress()
      See Socket.getRemoteSocketAddress().
      boolean getReuseAddress()
      See Socket.getReuseAddress().
      int getSendBufferSize()
      See Socket.getSendBufferSize().
      int getSoLinger()
      See Socket.getSoLinger().
      int getSoTimeout()
      See Socket.getSoTimeout().
      javax.net.ssl.SSLSocket getSslSocket()
      Returns the underlying SSLSocket if the mode is TLS.
      boolean getTcpNoDelay()
      See Socket.getTcpNoDelay().
      int getTrafficClass()
      See Socket.getTrafficClass().
      boolean isBound()
      See Socket.isBound().
      boolean isClosed()
      See Socket.isClosed().
      boolean isConnected()
      See Socket.isConnected().
      boolean isInputShutdown()
      See Socket.isInputShutdown().
      boolean isModeKnown()
      Returns true if the socket mode is not yet known.
      boolean isOutputShutdown()
      See Socket.isOutputShutdown().
      boolean isPlaintextSocket()
      Returns true if the socket mode has been determined to be PLAINTEXT.
      boolean isSecureSocket()
      Returns true if the socket mode has been determined to be TLS.
      void sendUrgentData​(int data)
      See Socket.sendUrgentData(int).
      void setKeepAlive​(boolean on)
      See Socket.setKeepAlive(boolean).
      void setOOBInline​(boolean on)
      See Socket.setOOBInline(boolean).
      void setPerformancePreferences​(int connectionTime, int latency, int bandwidth)
      See Socket.setPerformancePreferences(int, int, int).
      void setReceiveBufferSize​(int size)
      See Socket.setReceiveBufferSize(int).
      void setReuseAddress​(boolean on)
      See Socket.setReuseAddress(boolean).
      void setSendBufferSize​(int size)
      See Socket.setSendBufferSize(int).
      void setSoLinger​(boolean on, int linger)
      See Socket.setSoLinger(boolean, int).
      void setSoTimeout​(int timeout)
      See Socket.setSoTimeout(int).
      void setTcpNoDelay​(boolean on)
      See Socket.setTcpNoDelay(boolean).
      void setTrafficClass​(int tc)
      See Socket.setTrafficClass(int).
      void shutdownInput()
      See Socket.shutdownInput().
      void shutdownOutput()
      See Socket.shutdownOutput().
      java.lang.String toString()
      See Socket.toString().
      • Methods inherited from class java.net.Socket

        getOption, setOption, setSocketImplFactory, supportedOptions
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Method Detail

      • isSecureSocket

        public boolean isSecureSocket()
        Returns true if the socket mode has been determined to be TLS.
        Returns:
        true if the mode is TLS, false if it is UNKNOWN or PLAINTEXT.
      • isPlaintextSocket

        public boolean isPlaintextSocket()
        Returns true if the socket mode has been determined to be PLAINTEXT.
        Returns:
        true if the mode is PLAINTEXT, false if it is UNKNOWN or TLS.
      • isModeKnown

        public boolean isModeKnown()
        Returns true if the socket mode is not yet known.
        Returns:
        true if the mode is UNKNOWN, false if it is PLAINTEXT or TLS.
      • getSslSocket

        public javax.net.ssl.SSLSocket getSslSocket()
                                             throws java.io.IOException
        Returns the underlying SSLSocket if the mode is TLS. If the mode is UNKNOWN, causes mode detection which is a potentially blocking operation. If the mode ends up being PLAINTEXT, this will throw a SocketException, so callers are advised to only call this method after checking that isSecureSocket() returned true.
        Returns:
        the underlying SSLSocket if the mode is known to be TLS.
        Throws:
        java.io.IOException - if detecting the socket mode fails
        java.net.SocketException - if the mode is PLAINTEXT.
      • connect

        public void connect​(java.net.SocketAddress endpoint)
                     throws java.io.IOException
        See Socket.connect(SocketAddress). Calling this method does not trigger mode detection.
        Overrides:
        connect in class java.net.Socket
        Throws:
        java.io.IOException
      • connect

        public void connect​(java.net.SocketAddress endpoint,
                            int timeout)
                     throws java.io.IOException
        See Socket.connect(SocketAddress, int). Calling this method does not trigger mode detection.
        Overrides:
        connect in class java.net.Socket
        Throws:
        java.io.IOException
      • bind

        public void bind​(java.net.SocketAddress bindpoint)
                  throws java.io.IOException
        See Socket.bind(SocketAddress). Calling this method does not trigger mode detection.
        Overrides:
        bind in class java.net.Socket
        Throws:
        java.io.IOException
      • getInetAddress

        public java.net.InetAddress getInetAddress()
        See Socket.getInetAddress(). Calling this method does not trigger mode detection.
        Overrides:
        getInetAddress in class java.net.Socket
      • getLocalAddress

        public java.net.InetAddress getLocalAddress()
        See Socket.getLocalAddress(). Calling this method does not trigger mode detection.
        Overrides:
        getLocalAddress in class java.net.Socket
      • getPort

        public int getPort()
        See Socket.getPort(). Calling this method does not trigger mode detection.
        Overrides:
        getPort in class java.net.Socket
      • getLocalPort

        public int getLocalPort()
        See Socket.getLocalPort(). Calling this method does not trigger mode detection.
        Overrides:
        getLocalPort in class java.net.Socket
      • getRemoteSocketAddress

        public java.net.SocketAddress getRemoteSocketAddress()
        See Socket.getRemoteSocketAddress(). Calling this method does not trigger mode detection.
        Overrides:
        getRemoteSocketAddress in class java.net.Socket
      • getLocalSocketAddress

        public java.net.SocketAddress getLocalSocketAddress()
        See Socket.getLocalSocketAddress(). Calling this method does not trigger mode detection.
        Overrides:
        getLocalSocketAddress in class java.net.Socket
      • getChannel

        public java.nio.channels.SocketChannel getChannel()
        See Socket.getChannel(). Calling this method does not trigger mode detection.
        Overrides:
        getChannel in class java.net.Socket
      • getInputStream

        public java.io.InputStream getInputStream()
                                           throws java.io.IOException
        See Socket.getInputStream(). If the socket mode has not yet been detected, the first read from the returned input stream will trigger mode detection, which is a potentially blocking operation. This means the accept() thread should avoid reading from this input stream if possible.
        Overrides:
        getInputStream in class java.net.Socket
        Throws:
        java.io.IOException
      • getOutputStream

        public java.io.OutputStream getOutputStream()
                                             throws java.io.IOException
        See Socket.getOutputStream(). If the socket mode has not yet been detected, the first read from the returned input stream will trigger mode detection, which is a potentially blocking operation. This means the accept() thread should avoid reading from this input stream if possible.
        Overrides:
        getOutputStream in class java.net.Socket
        Throws:
        java.io.IOException
      • setTcpNoDelay

        public void setTcpNoDelay​(boolean on)
                           throws java.net.SocketException
        See Socket.setTcpNoDelay(boolean). Calling this method does not trigger mode detection.
        Overrides:
        setTcpNoDelay in class java.net.Socket
        Throws:
        java.net.SocketException
      • getTcpNoDelay

        public boolean getTcpNoDelay()
                              throws java.net.SocketException
        See Socket.getTcpNoDelay(). Calling this method does not trigger mode detection.
        Overrides:
        getTcpNoDelay in class java.net.Socket
        Throws:
        java.net.SocketException
      • setSoLinger

        public void setSoLinger​(boolean on,
                                int linger)
                         throws java.net.SocketException
        See Socket.setSoLinger(boolean, int). Calling this method does not trigger mode detection.
        Overrides:
        setSoLinger in class java.net.Socket
        Throws:
        java.net.SocketException
      • getSoLinger

        public int getSoLinger()
                        throws java.net.SocketException
        See Socket.getSoLinger(). Calling this method does not trigger mode detection.
        Overrides:
        getSoLinger in class java.net.Socket
        Throws:
        java.net.SocketException
      • sendUrgentData

        public void sendUrgentData​(int data)
                            throws java.io.IOException
        See Socket.sendUrgentData(int). Calling this method triggers mode detection, which is a potentially blocking operation, so it should not be done in the accept() thread.
        Overrides:
        sendUrgentData in class java.net.Socket
        Throws:
        java.io.IOException
      • setOOBInline

        public void setOOBInline​(boolean on)
                          throws java.net.SocketException
        See Socket.setOOBInline(boolean). Calling this method does not trigger mode detection.
        Overrides:
        setOOBInline in class java.net.Socket
        Throws:
        java.net.SocketException
      • getOOBInline

        public boolean getOOBInline()
                             throws java.net.SocketException
        See Socket.getOOBInline(). Calling this method does not trigger mode detection.
        Overrides:
        getOOBInline in class java.net.Socket
        Throws:
        java.net.SocketException
      • setSoTimeout

        public void setSoTimeout​(int timeout)
                          throws java.net.SocketException
        See Socket.setSoTimeout(int). Calling this method does not trigger mode detection.
        Overrides:
        setSoTimeout in class java.net.Socket
        Throws:
        java.net.SocketException
      • getSoTimeout

        public int getSoTimeout()
                         throws java.net.SocketException
        See Socket.getSoTimeout(). Calling this method does not trigger mode detection.
        Overrides:
        getSoTimeout in class java.net.Socket
        Throws:
        java.net.SocketException
      • setSendBufferSize

        public void setSendBufferSize​(int size)
                               throws java.net.SocketException
        See Socket.setSendBufferSize(int). Calling this method does not trigger mode detection.
        Overrides:
        setSendBufferSize in class java.net.Socket
        Throws:
        java.net.SocketException
      • getSendBufferSize

        public int getSendBufferSize()
                              throws java.net.SocketException
        See Socket.getSendBufferSize(). Calling this method does not trigger mode detection.
        Overrides:
        getSendBufferSize in class java.net.Socket
        Throws:
        java.net.SocketException
      • setReceiveBufferSize

        public void setReceiveBufferSize​(int size)
                                  throws java.net.SocketException
        See Socket.setReceiveBufferSize(int). Calling this method does not trigger mode detection.
        Overrides:
        setReceiveBufferSize in class java.net.Socket
        Throws:
        java.net.SocketException
      • getReceiveBufferSize

        public int getReceiveBufferSize()
                                 throws java.net.SocketException
        See Socket.getReceiveBufferSize(). Calling this method does not trigger mode detection.
        Overrides:
        getReceiveBufferSize in class java.net.Socket
        Throws:
        java.net.SocketException
      • setKeepAlive

        public void setKeepAlive​(boolean on)
                          throws java.net.SocketException
        See Socket.setKeepAlive(boolean). Calling this method does not trigger mode detection.
        Overrides:
        setKeepAlive in class java.net.Socket
        Throws:
        java.net.SocketException
      • getKeepAlive

        public boolean getKeepAlive()
                             throws java.net.SocketException
        See Socket.getKeepAlive(). Calling this method does not trigger mode detection.
        Overrides:
        getKeepAlive in class java.net.Socket
        Throws:
        java.net.SocketException
      • setTrafficClass

        public void setTrafficClass​(int tc)
                             throws java.net.SocketException
        See Socket.setTrafficClass(int). Calling this method does not trigger mode detection.
        Overrides:
        setTrafficClass in class java.net.Socket
        Throws:
        java.net.SocketException
      • getTrafficClass

        public int getTrafficClass()
                            throws java.net.SocketException
        See Socket.getTrafficClass(). Calling this method does not trigger mode detection.
        Overrides:
        getTrafficClass in class java.net.Socket
        Throws:
        java.net.SocketException
      • setReuseAddress

        public void setReuseAddress​(boolean on)
                             throws java.net.SocketException
        See Socket.setReuseAddress(boolean). Calling this method does not trigger mode detection.
        Overrides:
        setReuseAddress in class java.net.Socket
        Throws:
        java.net.SocketException
      • getReuseAddress

        public boolean getReuseAddress()
                                throws java.net.SocketException
        See Socket.getReuseAddress(). Calling this method does not trigger mode detection.
        Overrides:
        getReuseAddress in class java.net.Socket
        Throws:
        java.net.SocketException
      • close

        public void close()
                   throws java.io.IOException
        See Socket.close(). Calling this method does not trigger mode detection.
        Specified by:
        close in interface java.lang.AutoCloseable
        Specified by:
        close in interface java.io.Closeable
        Overrides:
        close in class java.net.Socket
        Throws:
        java.io.IOException
      • shutdownInput

        public void shutdownInput()
                           throws java.io.IOException
        See Socket.shutdownInput(). Calling this method does not trigger mode detection.
        Overrides:
        shutdownInput in class java.net.Socket
        Throws:
        java.io.IOException
      • shutdownOutput

        public void shutdownOutput()
                            throws java.io.IOException
        See Socket.shutdownOutput(). Calling this method does not trigger mode detection.
        Overrides:
        shutdownOutput in class java.net.Socket
        Throws:
        java.io.IOException
      • toString

        public java.lang.String toString()
        See Socket.toString(). Calling this method does not trigger mode detection.
        Overrides:
        toString in class java.net.Socket
      • isConnected

        public boolean isConnected()
        See Socket.isConnected(). Calling this method does not trigger mode detection.
        Overrides:
        isConnected in class java.net.Socket
      • isBound

        public boolean isBound()
        See Socket.isBound(). Calling this method does not trigger mode detection.
        Overrides:
        isBound in class java.net.Socket
      • isClosed

        public boolean isClosed()
        See Socket.isClosed(). Calling this method does not trigger mode detection.
        Overrides:
        isClosed in class java.net.Socket
      • isInputShutdown

        public boolean isInputShutdown()
        See Socket.isInputShutdown(). Calling this method does not trigger mode detection.
        Overrides:
        isInputShutdown in class java.net.Socket
      • isOutputShutdown

        public boolean isOutputShutdown()
        See Socket.isOutputShutdown(). Calling this method does not trigger mode detection.
        Overrides:
        isOutputShutdown in class java.net.Socket
      • setPerformancePreferences

        public void setPerformancePreferences​(int connectionTime,
                                              int latency,
                                              int bandwidth)
        See Socket.setPerformancePreferences(int, int, int). Calling this method does not trigger mode detection.
        Overrides:
        setPerformancePreferences in class java.net.Socket