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 TypeMethodDescriptionvoid
bind
(SocketAddress bindpoint) void
close()
SeeSocket.close()
.void
connect
(SocketAddress endpoint) void
connect
(SocketAddress endpoint, int timeout) SeeSocket.getChannel()
.boolean
int
boolean
int
getPort()
SeeSocket.getPort()
.int
boolean
int
int
SeeSocket.getSoLinger()
.int
Returns the underlying SSLSocket if the mode is TLS.boolean
int
boolean
isBound()
SeeSocket.isBound()
.boolean
isClosed()
SeeSocket.isClosed()
.boolean
SeeSocket.isConnected()
.boolean
boolean
Returns true if the socket mode is not yet known.boolean
boolean
Returns true if the socket mode has been determined to be PLAINTEXT.boolean
Returns true if the socket mode has been determined to be TLS.void
sendUrgentData
(int data) void
setKeepAlive
(boolean on) void
setOOBInline
(boolean on) void
setPerformancePreferences
(int connectionTime, int latency, int bandwidth) void
setReceiveBufferSize
(int size) void
setReuseAddress
(boolean on) void
setSendBufferSize
(int size) void
setSoLinger
(boolean on, int linger) void
setSoTimeout
(int timeout) void
setTcpNoDelay
(boolean on) void
setTrafficClass
(int tc) void
void
toString()
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:
connect
in classSocket
- Throws:
IOException
-
connect
SeeSocket.connect(SocketAddress, int)
. Calling this method does not trigger mode detection.- Overrides:
connect
in classSocket
- Throws:
IOException
-
bind
SeeSocket.bind(SocketAddress)
. Calling this method does not trigger mode detection.- Overrides:
bind
in classSocket
- Throws:
IOException
-
getInetAddress
SeeSocket.getInetAddress()
. Calling this method does not trigger mode detection.- Overrides:
getInetAddress
in classSocket
-
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
SeeSocket.getRemoteSocketAddress()
. Calling this method does not trigger mode detection.- Overrides:
getRemoteSocketAddress
in classSocket
-
getLocalSocketAddress
SeeSocket.getLocalSocketAddress()
. Calling this method does not trigger mode detection.- Overrides:
getLocalSocketAddress
in classSocket
-
getChannel
SeeSocket.getChannel()
. Calling this method does not trigger mode detection.- Overrides:
getChannel
in 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:
getInputStream
in 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:
getOutputStream
in classSocket
- Throws:
IOException
-
setTcpNoDelay
SeeSocket.setTcpNoDelay(boolean)
. Calling this method does not trigger mode detection.- Overrides:
setTcpNoDelay
in classSocket
- Throws:
SocketException
-
getTcpNoDelay
SeeSocket.getTcpNoDelay()
. Calling this method does not trigger mode detection.- Overrides:
getTcpNoDelay
in classSocket
- Throws:
SocketException
-
setSoLinger
SeeSocket.setSoLinger(boolean, int)
. Calling this method does not trigger mode detection.- Overrides:
setSoLinger
in classSocket
- Throws:
SocketException
-
getSoLinger
SeeSocket.getSoLinger()
. Calling this method does not trigger mode detection.- Overrides:
getSoLinger
in 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:
sendUrgentData
in classSocket
- Throws:
IOException
-
setOOBInline
SeeSocket.setOOBInline(boolean)
. Calling this method does not trigger mode detection.- Overrides:
setOOBInline
in classSocket
- Throws:
SocketException
-
getOOBInline
SeeSocket.getOOBInline()
. Calling this method does not trigger mode detection.- Overrides:
getOOBInline
in classSocket
- Throws:
SocketException
-
setSoTimeout
SeeSocket.setSoTimeout(int)
. Calling this method does not trigger mode detection.- Overrides:
setSoTimeout
in classSocket
- Throws:
SocketException
-
getSoTimeout
SeeSocket.getSoTimeout()
. Calling this method does not trigger mode detection.- Overrides:
getSoTimeout
in classSocket
- Throws:
SocketException
-
setSendBufferSize
SeeSocket.setSendBufferSize(int)
. Calling this method does not trigger mode detection.- Overrides:
setSendBufferSize
in classSocket
- Throws:
SocketException
-
getSendBufferSize
SeeSocket.getSendBufferSize()
. Calling this method does not trigger mode detection.- Overrides:
getSendBufferSize
in classSocket
- Throws:
SocketException
-
setReceiveBufferSize
SeeSocket.setReceiveBufferSize(int)
. Calling this method does not trigger mode detection.- Overrides:
setReceiveBufferSize
in classSocket
- Throws:
SocketException
-
getReceiveBufferSize
SeeSocket.getReceiveBufferSize()
. Calling this method does not trigger mode detection.- Overrides:
getReceiveBufferSize
in classSocket
- Throws:
SocketException
-
setKeepAlive
SeeSocket.setKeepAlive(boolean)
. Calling this method does not trigger mode detection.- Overrides:
setKeepAlive
in classSocket
- Throws:
SocketException
-
getKeepAlive
SeeSocket.getKeepAlive()
. Calling this method does not trigger mode detection.- Overrides:
getKeepAlive
in classSocket
- Throws:
SocketException
-
setTrafficClass
SeeSocket.setTrafficClass(int)
. Calling this method does not trigger mode detection.- Overrides:
setTrafficClass
in classSocket
- Throws:
SocketException
-
getTrafficClass
SeeSocket.getTrafficClass()
. Calling this method does not trigger mode detection.- Overrides:
getTrafficClass
in classSocket
- Throws:
SocketException
-
setReuseAddress
SeeSocket.setReuseAddress(boolean)
. Calling this method does not trigger mode detection.- Overrides:
setReuseAddress
in classSocket
- Throws:
SocketException
-
getReuseAddress
SeeSocket.getReuseAddress()
. Calling this method does not trigger mode detection.- Overrides:
getReuseAddress
in classSocket
- Throws:
SocketException
-
close
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
SeeSocket.shutdownInput()
. Calling this method does not trigger mode detection.- Overrides:
shutdownInput
in classSocket
- Throws:
IOException
-
shutdownOutput
SeeSocket.shutdownOutput()
. Calling this method does not trigger mode detection.- Overrides:
shutdownOutput
in 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:
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
-