8189338: JMX RMI Remote Mbean server connection hangs if the server stops responding during a SSL Handshake

Reviewed-by: smarks
This commit is contained in:
Daniel Jeliński 2023-01-04 13:17:29 +00:00
parent 82deb5ca61
commit 41900b57af
2 changed files with 28 additions and 18 deletions
src/java.rmi/share/classes/sun/rmi/transport/tcp
test/jdk/java/rmi/transport/handshakeTimeout

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -218,6 +218,19 @@ public class TCPChannel implements Channel {
conn = new TCPConnection(this, sock);
try {
/*
* 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
}
DataOutputStream out =
new DataOutputStream(conn.getOutputStream());
writeTransportHeader(out);
@ -229,19 +242,6 @@ public class TCPChannel implements Channel {
out.writeByte(TransportConstants.StreamProtocol);
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
}
DataInputStream in =
new DataInputStream(conn.getInputStream());
byte ack = in.readByte();

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -22,7 +22,7 @@
*/
/* @test
* @bug 4322806
* @bug 4322806 8189338
* @summary When an RMI (JRMP) connection is made to a TCP address that is
* listening, so the connection is accepted, but the server never responds
* to the initial JRMP handshake (nor does it terminate the connection),
@ -38,8 +38,11 @@
* java.rmi/sun.rmi.transport
* java.rmi/sun.rmi.transport.tcp
* @run main/othervm HandshakeTimeout
* @run main/othervm HandshakeTimeout SSL
*/
import javax.rmi.ssl.SslRMIClientSocketFactory;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.rmi.ConnectException;
import java.rmi.ConnectIOException;
@ -60,12 +63,19 @@ public class HandshakeTimeout {
* Listen on port, but never process connections made to it.
*/
ServerSocket serverSocket = new ServerSocket(0);
int port = serverSocket.getLocalPort();
InetSocketAddress address = (InetSocketAddress) serverSocket.getLocalSocketAddress();
/*
* Attempt RMI call to port in separate thread.
*/
Registry registry = LocateRegistry.getRegistry(port);
Registry registry;
if (args.length == 0) {
registry = LocateRegistry.getRegistry(address.getPort());
} else {
registry = LocateRegistry.getRegistry(address.getHostString(),
address.getPort(), new SslRMIClientSocketFactory());
}
Connector connector = new Connector(registry);
Thread t = new Thread(connector);
t.setDaemon(true);