Class UnifiedServerSocket.UnifiedSocket
- java.lang.Object
-
- java.net.Socket
-
- org.apache.zookeeper.server.quorum.UnifiedServerSocket.UnifiedSocket
-
- All Implemented Interfaces:
java.io.Closeable,java.lang.AutoCloseable
- Enclosing class:
- UnifiedServerSocket
public static class UnifiedServerSocket.UnifiedSocket extends java.net.SocketThe 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
All Methods Instance Methods Concrete Methods Modifier and Type Method Description voidbind(java.net.SocketAddress bindpoint)SeeSocket.bind(SocketAddress).voidclose()SeeSocket.close().voidconnect(java.net.SocketAddress endpoint)SeeSocket.connect(SocketAddress).voidconnect(java.net.SocketAddress endpoint, int timeout)SeeSocket.connect(SocketAddress, int).java.nio.channels.SocketChannelgetChannel()SeeSocket.getChannel().java.net.InetAddressgetInetAddress()SeeSocket.getInetAddress().java.io.InputStreamgetInputStream()SeeSocket.getInputStream().booleangetKeepAlive()SeeSocket.getKeepAlive().java.net.InetAddressgetLocalAddress()SeeSocket.getLocalAddress().intgetLocalPort()SeeSocket.getLocalPort().java.net.SocketAddressgetLocalSocketAddress()SeeSocket.getLocalSocketAddress().booleangetOOBInline()SeeSocket.getOOBInline().java.io.OutputStreamgetOutputStream()SeeSocket.getOutputStream().intgetPort()SeeSocket.getPort().intgetReceiveBufferSize()SeeSocket.getReceiveBufferSize().java.net.SocketAddressgetRemoteSocketAddress()SeeSocket.getRemoteSocketAddress().booleangetReuseAddress()SeeSocket.getReuseAddress().intgetSendBufferSize()SeeSocket.getSendBufferSize().intgetSoLinger()SeeSocket.getSoLinger().intgetSoTimeout()SeeSocket.getSoTimeout().javax.net.ssl.SSLSocketgetSslSocket()Returns the underlying SSLSocket if the mode is TLS.booleangetTcpNoDelay()SeeSocket.getTcpNoDelay().intgetTrafficClass()SeeSocket.getTrafficClass().booleanisBound()SeeSocket.isBound().booleanisClosed()SeeSocket.isClosed().booleanisConnected()SeeSocket.isConnected().booleanisInputShutdown()SeeSocket.isInputShutdown().booleanisModeKnown()Returns true if the socket mode is not yet known.booleanisOutputShutdown()SeeSocket.isOutputShutdown().booleanisPlaintextSocket()Returns true if the socket mode has been determined to be PLAINTEXT.booleanisSecureSocket()Returns true if the socket mode has been determined to be TLS.voidsendUrgentData(int data)SeeSocket.sendUrgentData(int).voidsetKeepAlive(boolean on)SeeSocket.setKeepAlive(boolean).voidsetOOBInline(boolean on)SeeSocket.setOOBInline(boolean).voidsetPerformancePreferences(int connectionTime, int latency, int bandwidth)SeeSocket.setPerformancePreferences(int, int, int).voidsetReceiveBufferSize(int size)SeeSocket.setReceiveBufferSize(int).voidsetReuseAddress(boolean on)SeeSocket.setReuseAddress(boolean).voidsetSendBufferSize(int size)SeeSocket.setSendBufferSize(int).voidsetSoLinger(boolean on, int linger)SeeSocket.setSoLinger(boolean, int).voidsetSoTimeout(int timeout)SeeSocket.setSoTimeout(int).voidsetTcpNoDelay(boolean on)SeeSocket.setTcpNoDelay(boolean).voidsetTrafficClass(int tc)SeeSocket.setTrafficClass(int).voidshutdownInput()SeeSocket.shutdownInput().voidshutdownOutput()SeeSocket.shutdownOutput().java.lang.StringtoString()SeeSocket.toString().
-
-
-
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.IOExceptionReturns 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:
java.io.IOException- if detecting the socket mode failsjava.net.SocketException- if the mode is PLAINTEXT.
-
connect
public void connect(java.net.SocketAddress endpoint) throws java.io.IOExceptionSeeSocket.connect(SocketAddress). Calling this method does not trigger mode detection.- Overrides:
connectin classjava.net.Socket- Throws:
java.io.IOException
-
connect
public void connect(java.net.SocketAddress endpoint, int timeout) throws java.io.IOExceptionSeeSocket.connect(SocketAddress, int). Calling this method does not trigger mode detection.- Overrides:
connectin classjava.net.Socket- Throws:
java.io.IOException
-
bind
public void bind(java.net.SocketAddress bindpoint) throws java.io.IOExceptionSeeSocket.bind(SocketAddress). Calling this method does not trigger mode detection.- Overrides:
bindin classjava.net.Socket- Throws:
java.io.IOException
-
getInetAddress
public java.net.InetAddress getInetAddress()
SeeSocket.getInetAddress(). Calling this method does not trigger mode detection.- Overrides:
getInetAddressin classjava.net.Socket
-
getLocalAddress
public java.net.InetAddress getLocalAddress()
SeeSocket.getLocalAddress(). Calling this method does not trigger mode detection.- Overrides:
getLocalAddressin classjava.net.Socket
-
getPort
public int getPort()
SeeSocket.getPort(). Calling this method does not trigger mode detection.- Overrides:
getPortin classjava.net.Socket
-
getLocalPort
public int getLocalPort()
SeeSocket.getLocalPort(). Calling this method does not trigger mode detection.- Overrides:
getLocalPortin classjava.net.Socket
-
getRemoteSocketAddress
public java.net.SocketAddress getRemoteSocketAddress()
SeeSocket.getRemoteSocketAddress(). Calling this method does not trigger mode detection.- Overrides:
getRemoteSocketAddressin classjava.net.Socket
-
getLocalSocketAddress
public java.net.SocketAddress getLocalSocketAddress()
SeeSocket.getLocalSocketAddress(). Calling this method does not trigger mode detection.- Overrides:
getLocalSocketAddressin classjava.net.Socket
-
getChannel
public java.nio.channels.SocketChannel getChannel()
SeeSocket.getChannel(). Calling this method does not trigger mode detection.- Overrides:
getChannelin classjava.net.Socket
-
getInputStream
public java.io.InputStream getInputStream() throws java.io.IOExceptionSeeSocket.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:
getInputStreamin classjava.net.Socket- Throws:
java.io.IOException
-
getOutputStream
public java.io.OutputStream getOutputStream() throws java.io.IOExceptionSeeSocket.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:
getOutputStreamin classjava.net.Socket- Throws:
java.io.IOException
-
setTcpNoDelay
public void setTcpNoDelay(boolean on) throws java.net.SocketExceptionSeeSocket.setTcpNoDelay(boolean). Calling this method does not trigger mode detection.- Overrides:
setTcpNoDelayin classjava.net.Socket- Throws:
java.net.SocketException
-
getTcpNoDelay
public boolean getTcpNoDelay() throws java.net.SocketExceptionSeeSocket.getTcpNoDelay(). Calling this method does not trigger mode detection.- Overrides:
getTcpNoDelayin classjava.net.Socket- Throws:
java.net.SocketException
-
setSoLinger
public void setSoLinger(boolean on, int linger) throws java.net.SocketExceptionSeeSocket.setSoLinger(boolean, int). Calling this method does not trigger mode detection.- Overrides:
setSoLingerin classjava.net.Socket- Throws:
java.net.SocketException
-
getSoLinger
public int getSoLinger() throws java.net.SocketExceptionSeeSocket.getSoLinger(). Calling this method does not trigger mode detection.- Overrides:
getSoLingerin classjava.net.Socket- Throws:
java.net.SocketException
-
sendUrgentData
public void sendUrgentData(int data) throws java.io.IOExceptionSeeSocket.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:
sendUrgentDatain classjava.net.Socket- Throws:
java.io.IOException
-
setOOBInline
public void setOOBInline(boolean on) throws java.net.SocketExceptionSeeSocket.setOOBInline(boolean). Calling this method does not trigger mode detection.- Overrides:
setOOBInlinein classjava.net.Socket- Throws:
java.net.SocketException
-
getOOBInline
public boolean getOOBInline() throws java.net.SocketExceptionSeeSocket.getOOBInline(). Calling this method does not trigger mode detection.- Overrides:
getOOBInlinein classjava.net.Socket- Throws:
java.net.SocketException
-
setSoTimeout
public void setSoTimeout(int timeout) throws java.net.SocketExceptionSeeSocket.setSoTimeout(int). Calling this method does not trigger mode detection.- Overrides:
setSoTimeoutin classjava.net.Socket- Throws:
java.net.SocketException
-
getSoTimeout
public int getSoTimeout() throws java.net.SocketExceptionSeeSocket.getSoTimeout(). Calling this method does not trigger mode detection.- Overrides:
getSoTimeoutin classjava.net.Socket- Throws:
java.net.SocketException
-
setSendBufferSize
public void setSendBufferSize(int size) throws java.net.SocketExceptionSeeSocket.setSendBufferSize(int). Calling this method does not trigger mode detection.- Overrides:
setSendBufferSizein classjava.net.Socket- Throws:
java.net.SocketException
-
getSendBufferSize
public int getSendBufferSize() throws java.net.SocketExceptionSeeSocket.getSendBufferSize(). Calling this method does not trigger mode detection.- Overrides:
getSendBufferSizein classjava.net.Socket- Throws:
java.net.SocketException
-
setReceiveBufferSize
public void setReceiveBufferSize(int size) throws java.net.SocketExceptionSeeSocket.setReceiveBufferSize(int). Calling this method does not trigger mode detection.- Overrides:
setReceiveBufferSizein classjava.net.Socket- Throws:
java.net.SocketException
-
getReceiveBufferSize
public int getReceiveBufferSize() throws java.net.SocketExceptionSeeSocket.getReceiveBufferSize(). Calling this method does not trigger mode detection.- Overrides:
getReceiveBufferSizein classjava.net.Socket- Throws:
java.net.SocketException
-
setKeepAlive
public void setKeepAlive(boolean on) throws java.net.SocketExceptionSeeSocket.setKeepAlive(boolean). Calling this method does not trigger mode detection.- Overrides:
setKeepAlivein classjava.net.Socket- Throws:
java.net.SocketException
-
getKeepAlive
public boolean getKeepAlive() throws java.net.SocketExceptionSeeSocket.getKeepAlive(). Calling this method does not trigger mode detection.- Overrides:
getKeepAlivein classjava.net.Socket- Throws:
java.net.SocketException
-
setTrafficClass
public void setTrafficClass(int tc) throws java.net.SocketExceptionSeeSocket.setTrafficClass(int). Calling this method does not trigger mode detection.- Overrides:
setTrafficClassin classjava.net.Socket- Throws:
java.net.SocketException
-
getTrafficClass
public int getTrafficClass() throws java.net.SocketExceptionSeeSocket.getTrafficClass(). Calling this method does not trigger mode detection.- Overrides:
getTrafficClassin classjava.net.Socket- Throws:
java.net.SocketException
-
setReuseAddress
public void setReuseAddress(boolean on) throws java.net.SocketExceptionSeeSocket.setReuseAddress(boolean). Calling this method does not trigger mode detection.- Overrides:
setReuseAddressin classjava.net.Socket- Throws:
java.net.SocketException
-
getReuseAddress
public boolean getReuseAddress() throws java.net.SocketExceptionSeeSocket.getReuseAddress(). Calling this method does not trigger mode detection.- Overrides:
getReuseAddressin classjava.net.Socket- Throws:
java.net.SocketException
-
close
public void close() throws java.io.IOExceptionSeeSocket.close(). Calling this method does not trigger mode detection.- Specified by:
closein interfacejava.lang.AutoCloseable- Specified by:
closein interfacejava.io.Closeable- Overrides:
closein classjava.net.Socket- Throws:
java.io.IOException
-
shutdownInput
public void shutdownInput() throws java.io.IOExceptionSeeSocket.shutdownInput(). Calling this method does not trigger mode detection.- Overrides:
shutdownInputin classjava.net.Socket- Throws:
java.io.IOException
-
shutdownOutput
public void shutdownOutput() throws java.io.IOExceptionSeeSocket.shutdownOutput(). Calling this method does not trigger mode detection.- Overrides:
shutdownOutputin classjava.net.Socket- Throws:
java.io.IOException
-
toString
public java.lang.String toString()
SeeSocket.toString(). Calling this method does not trigger mode detection.- Overrides:
toStringin classjava.net.Socket
-
isConnected
public boolean isConnected()
SeeSocket.isConnected(). Calling this method does not trigger mode detection.- Overrides:
isConnectedin classjava.net.Socket
-
isBound
public boolean isBound()
SeeSocket.isBound(). Calling this method does not trigger mode detection.- Overrides:
isBoundin classjava.net.Socket
-
isClosed
public boolean isClosed()
SeeSocket.isClosed(). Calling this method does not trigger mode detection.- Overrides:
isClosedin classjava.net.Socket
-
isInputShutdown
public boolean isInputShutdown()
SeeSocket.isInputShutdown(). Calling this method does not trigger mode detection.- Overrides:
isInputShutdownin classjava.net.Socket
-
isOutputShutdown
public boolean isOutputShutdown()
SeeSocket.isOutputShutdown(). Calling this method does not trigger mode detection.- Overrides:
isOutputShutdownin classjava.net.Socket
-
setPerformancePreferences
public void setPerformancePreferences(int connectionTime, int latency, int bandwidth)SeeSocket.setPerformancePreferences(int, int, int). Calling this method does not trigger mode detection.- Overrides:
setPerformancePreferencesin classjava.net.Socket
-
-