Potential infinite waiting at JMXConnection#createConnection
KUBOTA Yuji
kubota.yuji at gmail.com
Mon May 4 16:19:54 UTC 2015
Hi all,
I want to contribute this issue.
If there are a problem about this patch or a better way for openjdk
community, please advise me.
Thanks for
2015-04-22 0:31 GMT+09:00 KUBOTA Yuji <kubota.yuji at gmail.com>:
> Hi all,
>
> I found an infinite waiting at TCPChannel#createConnection.
> This method flushes the DataOutputStream without the socket timeout settings
> when choose stream protocol [1].
>
> If connection lost (the destination server do no return response)
> during the flush,
> this method has possibilities to take long time beyond the expectations
> at java.net.SocketInputStream.socketRead0 as following stack trace.
>
> stack trace :
> at java.net.SocketInputStream.socketRead0(SocketInputStream.java)
> at java.net.SocketInputStream.read(SocketInputStream.java)
> at java.net.SocketInputStream.read(SocketInputStream.java)
> at sun.security.ssl.InputRecord.readFully(InputRecord.java)
> at sun.security.ssl.InputRecord.read(InputRecord.java)
> at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java)
> at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java)
> at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java)
> at sun.security.ssl.AppOutputStream.write(AppOutputStream.java)
> at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java)
> at java.io.BufferedOutputStream.flush(BufferedOutputStream.java)
> at java.io.DataOutputStream.flush(DataOutputStream.java)
> at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java)
> at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java)
> at sun.rmi.server.UnicastRef.invoke(UnicastRef.java)
> at javax.management.remote.rmi.RMIServerImpl_Stub.newClient
> at javax.management.remote.rmi.RMIConnector.getConnection(RMIConnector.java)
> at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java)
> at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java)
>
> When create connection, we cannot set the timeout by properties.
> Therefore, JMX sets the default value of SO_TIMEOUT, i.e., infinite.
> So I wrote a patch to fix this infinite waiting by using property-configured value:
> sun.rmi.transport.tcp.responseTimeout.
>
> Please review this patch. :)
>
> Note: My OCA has been processed a few hour ago, so my name may take a
> short time to
> appear on the OCA signatories page.
>
> Thanks,
> KUBOTA Yuji
>
> [1]: http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/c5b5d9045728/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPConnection.java#l191
>
> diff --git a/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPChannel.java
> b/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPChannel.java
> --- a/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPChannel.java
> +++ b/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPChannel.java
> @@ -222,20 +222,34 @@
> // choose protocol (single op if not reusable socket)
> if (!conn.isReusable()) {
> out.writeByte(TransportConstants.SingleOpProtocol);
> } else {
> out.writeByte(TransportConstants.StreamProtocol);
> +
> + int usableSoTimeout = 0;
> + try {
> + /*
> + * If socket factory had set a zero timeout on its own,
> + * then set the property-configured value to prevent
> + * an infinite waiting.
> + */
> + usableSoTimeout = sock.getSoTimeout();
> + if (usableSoTimeout == 0) {
> + usableSoTimeout = responseTimeout;
> + }
> + sock.setSoTimeout(usableSoTimeout);
> + } catch (Exception e) {
> + // if we fail to set this, ignore and proceed anyway
> + }
> out.flush();
>
> /*
> * Set socket read timeout to configured value for JRMP
> * connection handshake; this also serves to guard against
> * non-JRMP servers that do not respond (see 4322806).
> */
> - int originalSoTimeout = 0;
> try {
> - originalSoTimeout = sock.getSoTimeout();
> sock.setSoTimeout(handshakeTimeout);
> } catch (Exception e) {
> // if we fail to set this, ignore and proceed anyway
> }
>
> @@ -279,18 +293,11 @@
> * connection. NOTE: this timeout, if configured to a
> * finite duration, places an upper bound on the time
> * that a remote method call is permitted to execute.
> */
> try {
> - /*
> - * If socket factory had set a non-zero timeout on its
> - * own, then restore it instead of using the property-
> - * configured value.
> - */
> - sock.setSoTimeout((originalSoTimeout != 0 ?
> - originalSoTimeout :
> - responseTimeout));
> + sock.setSoTimeout(usableSoTimeout);
> } catch (Exception e) {
> // if we fail to set this, ignore and proceed anyway
> }
>
> out.flush();
More information about the jdk9-dev
mailing list