Class UnifiedServerSocket.UnifiedSocket
- java.lang.Object
-
- java.net.Socket
-
- org.apache.zookeeper.server.quorum.UnifiedServerSocket.UnifiedSocket
-
- All Implemented Interfaces:
Closeable
,AutoCloseable
- Enclosing class:
- UnifiedServerSocket
public static class UnifiedServerSocket.UnifiedSocket extends 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 asSocket.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 callingisSecureSocket()
, and can get the underlying SSLSocket by callinggetSslSocket()
.
-
-
Method Summary
-
Methods inherited from class java.net.Socket
setSocketImplFactory
-
-
-
-
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 SSLSocket getSslSocket() throws 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 thatisSecureSocket()
returned true.- Returns:
- the underlying SSLSocket if the mode is known to be TLS.
- Throws:
IOException
- if detecting the socket mode failsSocketException
- if the mode is PLAINTEXT.
-
connect
public void connect(SocketAddress endpoint) throws IOException
SeeSocket.connect(SocketAddress)
. Calling this method does not trigger mode detection.- Overrides:
connect
in classSocket
- Throws:
IOException
-
connect
public void connect(SocketAddress endpoint, int timeout) throws IOException
SeeSocket.connect(SocketAddress, int)
. Calling this method does not trigger mode detection.- Overrides:
connect
in classSocket
- Throws:
IOException
-
bind
public void bind(SocketAddress bindpoint) throws IOException
SeeSocket.bind(SocketAddress)
. Calling this method does not trigger mode detection.- Overrides:
bind
in classSocket
- Throws:
IOException
-
getInetAddress
public InetAddress getInetAddress()
SeeSocket.getInetAddress()
. Calling this method does not trigger mode detection.- Overrides:
getInetAddress
in classSocket
-
getLocalAddress
public InetAddress getLocalAddress()
SeeSocket.getLocalAddress()
. Calling this method does not trigger mode detection.- Overrides:
getLocalAddress
in classSocket
-
getPort
public int getPort()
SeeSocket.getPort()
. Calling this method does not trigger mode detection.
-
getLocalPort
public int getLocalPort()
SeeSocket.getLocalPort()
. Calling this method does not trigger mode detection.- Overrides:
getLocalPort
in classSocket
-
getRemoteSocketAddress
public SocketAddress getRemoteSocketAddress()
SeeSocket.getRemoteSocketAddress()
. Calling this method does not trigger mode detection.- Overrides:
getRemoteSocketAddress
in classSocket
-
getLocalSocketAddress
public SocketAddress getLocalSocketAddress()
SeeSocket.getLocalSocketAddress()
. Calling this method does not trigger mode detection.- Overrides:
getLocalSocketAddress
in classSocket
-
getChannel
public SocketChannel getChannel()
SeeSocket.getChannel()
. Calling this method does not trigger mode detection.- Overrides:
getChannel
in classSocket
-
getInputStream
public InputStream getInputStream() throws IOException
SeeSocket.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 classSocket
- Throws:
IOException
-
getOutputStream
public OutputStream getOutputStream() throws IOException
SeeSocket.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 classSocket
- Throws:
IOException
-
setTcpNoDelay
public void setTcpNoDelay(boolean on) throws SocketException
SeeSocket.setTcpNoDelay(boolean)
. Calling this method does not trigger mode detection.- Overrides:
setTcpNoDelay
in classSocket
- Throws:
SocketException
-
getTcpNoDelay
public boolean getTcpNoDelay() throws SocketException
SeeSocket.getTcpNoDelay()
. Calling this method does not trigger mode detection.- Overrides:
getTcpNoDelay
in classSocket
- Throws:
SocketException
-
setSoLinger
public void setSoLinger(boolean on, int linger) throws SocketException
SeeSocket.setSoLinger(boolean, int)
. Calling this method does not trigger mode detection.- Overrides:
setSoLinger
in classSocket
- Throws:
SocketException
-
getSoLinger
public int getSoLinger() throws SocketException
SeeSocket.getSoLinger()
. Calling this method does not trigger mode detection.- Overrides:
getSoLinger
in classSocket
- Throws:
SocketException
-
sendUrgentData
public void sendUrgentData(int data) throws IOException
SeeSocket.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 classSocket
- Throws:
IOException
-
setOOBInline
public void setOOBInline(boolean on) throws SocketException
SeeSocket.setOOBInline(boolean)
. Calling this method does not trigger mode detection.- Overrides:
setOOBInline
in classSocket
- Throws:
SocketException
-
getOOBInline
public boolean getOOBInline() throws SocketException
SeeSocket.getOOBInline()
. Calling this method does not trigger mode detection.- Overrides:
getOOBInline
in classSocket
- Throws:
SocketException
-
setSoTimeout
public void setSoTimeout(int timeout) throws SocketException
SeeSocket.setSoTimeout(int)
. Calling this method does not trigger mode detection.- Overrides:
setSoTimeout
in classSocket
- Throws:
SocketException
-
getSoTimeout
public int getSoTimeout() throws SocketException
SeeSocket.getSoTimeout()
. Calling this method does not trigger mode detection.- Overrides:
getSoTimeout
in classSocket
- Throws:
SocketException
-
setSendBufferSize
public void setSendBufferSize(int size) throws SocketException
SeeSocket.setSendBufferSize(int)
. Calling this method does not trigger mode detection.- Overrides:
setSendBufferSize
in classSocket
- Throws:
SocketException
-
getSendBufferSize
public int getSendBufferSize() throws SocketException
SeeSocket.getSendBufferSize()
. Calling this method does not trigger mode detection.- Overrides:
getSendBufferSize
in classSocket
- Throws:
SocketException
-
setReceiveBufferSize
public void setReceiveBufferSize(int size) throws SocketException
SeeSocket.setReceiveBufferSize(int)
. Calling this method does not trigger mode detection.- Overrides:
setReceiveBufferSize
in classSocket
- Throws:
SocketException
-
getReceiveBufferSize
public int getReceiveBufferSize() throws SocketException
SeeSocket.getReceiveBufferSize()
. Calling this method does not trigger mode detection.- Overrides:
getReceiveBufferSize
in classSocket
- Throws:
SocketException
-
setKeepAlive
public void setKeepAlive(boolean on) throws SocketException
SeeSocket.setKeepAlive(boolean)
. Calling this method does not trigger mode detection.- Overrides:
setKeepAlive
in classSocket
- Throws:
SocketException
-
getKeepAlive
public boolean getKeepAlive() throws SocketException
SeeSocket.getKeepAlive()
. Calling this method does not trigger mode detection.- Overrides:
getKeepAlive
in classSocket
- Throws:
SocketException
-
setTrafficClass
public void setTrafficClass(int tc) throws SocketException
SeeSocket.setTrafficClass(int)
. Calling this method does not trigger mode detection.- Overrides:
setTrafficClass
in classSocket
- Throws:
SocketException
-
getTrafficClass
public int getTrafficClass() throws SocketException
SeeSocket.getTrafficClass()
. Calling this method does not trigger mode detection.- Overrides:
getTrafficClass
in classSocket
- Throws:
SocketException
-
setReuseAddress
public void setReuseAddress(boolean on) throws SocketException
SeeSocket.setReuseAddress(boolean)
. Calling this method does not trigger mode detection.- Overrides:
setReuseAddress
in classSocket
- Throws:
SocketException
-
getReuseAddress
public boolean getReuseAddress() throws SocketException
SeeSocket.getReuseAddress()
. Calling this method does not trigger mode detection.- Overrides:
getReuseAddress
in classSocket
- Throws:
SocketException
-
close
public void close() throws IOException
SeeSocket.close()
. Calling this method does not trigger mode detection.- Specified by:
close
in interfaceAutoCloseable
- Specified by:
close
in interfaceCloseable
- Overrides:
close
in classSocket
- Throws:
IOException
-
shutdownInput
public void shutdownInput() throws IOException
SeeSocket.shutdownInput()
. Calling this method does not trigger mode detection.- Overrides:
shutdownInput
in classSocket
- Throws:
IOException
-
shutdownOutput
public void shutdownOutput() throws IOException
SeeSocket.shutdownOutput()
. Calling this method does not trigger mode detection.- Overrides:
shutdownOutput
in classSocket
- Throws:
IOException
-
toString
public String toString()
SeeSocket.toString()
. Calling this method does not trigger mode detection.
-
isConnected
public boolean isConnected()
SeeSocket.isConnected()
. Calling this method does not trigger mode detection.- Overrides:
isConnected
in classSocket
-
isBound
public boolean isBound()
SeeSocket.isBound()
. Calling this method does not trigger mode detection.
-
isClosed
public boolean isClosed()
SeeSocket.isClosed()
. Calling this method does not trigger mode detection.
-
isInputShutdown
public boolean isInputShutdown()
SeeSocket.isInputShutdown()
. Calling this method does not trigger mode detection.- Overrides:
isInputShutdown
in classSocket
-
isOutputShutdown
public boolean isOutputShutdown()
SeeSocket.isOutputShutdown()
. Calling this method does not trigger mode detection.- Overrides:
isOutputShutdown
in classSocket
-
setPerformancePreferences
public void setPerformancePreferences(int connectionTime, int latency, int bandwidth)
SeeSocket.setPerformancePreferences(int, int, int)
. Calling this method does not trigger mode detection.- Overrides:
setPerformancePreferences
in classSocket
-
-