Class UnifiedServerSocket.UnifiedSocket
java.lang.Object
java.net.Socket
org.apache.zookeeper.server.quorum.UnifiedServerSocket.UnifiedSocket
- All Implemented Interfaces:
Closeable,AutoCloseable
- Enclosing class:
- UnifiedServerSocket
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
Modifier and TypeMethodDescriptionvoidbind(SocketAddress bindpoint) voidclose()SeeSocket.close().voidconnect(SocketAddress endpoint) voidconnect(SocketAddress endpoint, int timeout) SeeSocket.getChannel().booleanintbooleanintgetPort()SeeSocket.getPort().intbooleanintintSeeSocket.getSoLinger().intReturns the underlying SSLSocket if the mode is TLS.booleanintbooleanisBound()SeeSocket.isBound().booleanisClosed()SeeSocket.isClosed().booleanSeeSocket.isConnected().booleanbooleanReturns true if the socket mode is not yet known.booleanbooleanReturns true if the socket mode has been determined to be PLAINTEXT.booleanReturns true if the socket mode has been determined to be TLS.voidsendUrgentData(int data) voidsetKeepAlive(boolean on) voidsetOOBInline(boolean on) voidsetPerformancePreferences(int connectionTime, int latency, int bandwidth) voidsetReceiveBufferSize(int size) voidsetReuseAddress(boolean on) voidsetSendBufferSize(int size) voidsetSoLinger(boolean on, int linger) voidsetSoTimeout(int timeout) voidsetTcpNoDelay(boolean on) voidsetTrafficClass(int tc) voidvoidtoString()SeeSocket.toString().Methods inherited from class java.net.Socket
setSocketImplFactory
-
Method Details
-
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
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
SeeSocket.connect(SocketAddress). Calling this method does not trigger mode detection.- Overrides:
connectin classSocket- Throws:
IOException
-
connect
SeeSocket.connect(SocketAddress, int). Calling this method does not trigger mode detection.- Overrides:
connectin classSocket- Throws:
IOException
-
bind
SeeSocket.bind(SocketAddress). Calling this method does not trigger mode detection.- Overrides:
bindin classSocket- Throws:
IOException
-
getInetAddress
SeeSocket.getInetAddress(). Calling this method does not trigger mode detection.- Overrides:
getInetAddressin classSocket
-
getLocalAddress
SeeSocket.getLocalAddress(). Calling this method does not trigger mode detection.- Overrides:
getLocalAddressin 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:
getLocalPortin classSocket
-
getRemoteSocketAddress
SeeSocket.getRemoteSocketAddress(). Calling this method does not trigger mode detection.- Overrides:
getRemoteSocketAddressin classSocket
-
getLocalSocketAddress
SeeSocket.getLocalSocketAddress(). Calling this method does not trigger mode detection.- Overrides:
getLocalSocketAddressin classSocket
-
getChannel
SeeSocket.getChannel(). Calling this method does not trigger mode detection.- Overrides:
getChannelin classSocket
-
getInputStream
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:
getInputStreamin classSocket- Throws:
IOException
-
getOutputStream
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:
getOutputStreamin classSocket- Throws:
IOException
-
setTcpNoDelay
SeeSocket.setTcpNoDelay(boolean). Calling this method does not trigger mode detection.- Overrides:
setTcpNoDelayin classSocket- Throws:
SocketException
-
getTcpNoDelay
SeeSocket.getTcpNoDelay(). Calling this method does not trigger mode detection.- Overrides:
getTcpNoDelayin classSocket- Throws:
SocketException
-
setSoLinger
SeeSocket.setSoLinger(boolean, int). Calling this method does not trigger mode detection.- Overrides:
setSoLingerin classSocket- Throws:
SocketException
-
getSoLinger
SeeSocket.getSoLinger(). Calling this method does not trigger mode detection.- Overrides:
getSoLingerin classSocket- Throws:
SocketException
-
sendUrgentData
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:
sendUrgentDatain classSocket- Throws:
IOException
-
setOOBInline
SeeSocket.setOOBInline(boolean). Calling this method does not trigger mode detection.- Overrides:
setOOBInlinein classSocket- Throws:
SocketException
-
getOOBInline
SeeSocket.getOOBInline(). Calling this method does not trigger mode detection.- Overrides:
getOOBInlinein classSocket- Throws:
SocketException
-
setSoTimeout
SeeSocket.setSoTimeout(int). Calling this method does not trigger mode detection.- Overrides:
setSoTimeoutin classSocket- Throws:
SocketException
-
getSoTimeout
SeeSocket.getSoTimeout(). Calling this method does not trigger mode detection.- Overrides:
getSoTimeoutin classSocket- Throws:
SocketException
-
setSendBufferSize
SeeSocket.setSendBufferSize(int). Calling this method does not trigger mode detection.- Overrides:
setSendBufferSizein classSocket- Throws:
SocketException
-
getSendBufferSize
SeeSocket.getSendBufferSize(). Calling this method does not trigger mode detection.- Overrides:
getSendBufferSizein classSocket- Throws:
SocketException
-
setReceiveBufferSize
SeeSocket.setReceiveBufferSize(int). Calling this method does not trigger mode detection.- Overrides:
setReceiveBufferSizein classSocket- Throws:
SocketException
-
getReceiveBufferSize
SeeSocket.getReceiveBufferSize(). Calling this method does not trigger mode detection.- Overrides:
getReceiveBufferSizein classSocket- Throws:
SocketException
-
setKeepAlive
SeeSocket.setKeepAlive(boolean). Calling this method does not trigger mode detection.- Overrides:
setKeepAlivein classSocket- Throws:
SocketException
-
getKeepAlive
SeeSocket.getKeepAlive(). Calling this method does not trigger mode detection.- Overrides:
getKeepAlivein classSocket- Throws:
SocketException
-
setTrafficClass
SeeSocket.setTrafficClass(int). Calling this method does not trigger mode detection.- Overrides:
setTrafficClassin classSocket- Throws:
SocketException
-
getTrafficClass
SeeSocket.getTrafficClass(). Calling this method does not trigger mode detection.- Overrides:
getTrafficClassin classSocket- Throws:
SocketException
-
setReuseAddress
SeeSocket.setReuseAddress(boolean). Calling this method does not trigger mode detection.- Overrides:
setReuseAddressin classSocket- Throws:
SocketException
-
getReuseAddress
SeeSocket.getReuseAddress(). Calling this method does not trigger mode detection.- Overrides:
getReuseAddressin classSocket- Throws:
SocketException
-
close
SeeSocket.close(). Calling this method does not trigger mode detection.- Specified by:
closein interfaceAutoCloseable- Specified by:
closein interfaceCloseable- Overrides:
closein classSocket- Throws:
IOException
-
shutdownInput
SeeSocket.shutdownInput(). Calling this method does not trigger mode detection.- Overrides:
shutdownInputin classSocket- Throws:
IOException
-
shutdownOutput
SeeSocket.shutdownOutput(). Calling this method does not trigger mode detection.- Overrides:
shutdownOutputin classSocket- Throws:
IOException
-
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:
isConnectedin 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:
isInputShutdownin classSocket
-
isOutputShutdown
public boolean isOutputShutdown()SeeSocket.isOutputShutdown(). Calling this method does not trigger mode detection.- Overrides:
isOutputShutdownin 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:
setPerformancePreferencesin classSocket
-