/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* RMIMasterSocketFactory attempts to create a socket connection to the
* specified host using successively less efficient mechanisms
* until one succeeds. If the host is successfully connected to,
* the factory for the successful mechanism is stored in an internal
* hash table keyed by the host name, so that future attempts to
* connect to the same host will automatically use the same
* mechanism.
*/
/** "proxy" package log level */
}
/* proxy package log */
/** timeout for attemping direct socket connections */
private static long getConnectTimeout() {
new GetLongAction("sun.rmi.transport.proxy.connectTimeout",
}
/** whether to fallback to HTTP on general connect failures */
private static final boolean eagerHttpFallback =
"sun.rmi.transport.proxy.eagerHttpFallback")).booleanValue();
/** table of hosts successfully connected to and the factory used */
new Hashtable<>();
/** maximum number of hosts to remember successful connection to */
/** list of the hosts in successTable in initial connection order */
/** default factory for initial use for direct socket connection */
/** ordered list of factories to try as alternate connection
* mechanisms if a direct socket connections fails */
/**
* Create a RMIMasterSocketFactory object. Establish order of
* connection mechanisms to attempt on createSocket, if a direct
* socket connection fails.
*/
public RMIMasterSocketFactory() {
boolean setFactories = false;
try {
if (!tmp.booleanValue() &&
setFactories = true;
}
} catch (Exception e) {
// unable to obtain the properties, so assume default behavior.
setFactories = true;
}
if (setFactories) {
}
}
/**
* Create a new client socket. If we remember connecting to this host
* successfully before, then use the same factory again. Otherwise,
* try using a direct socket connection and then the alternate factories
* in the order specified in altFactoryList.
*/
throws IOException
{
}
/*
* If we don't have any alternate factories to consult, short circuit
* the fallback procedure and delegate to the initial factory.
*/
}
/*
* If we remember successfully connecting to this host before,
* use the same factory.
*/
"previously successful factory found: " + factory);
}
}
/*
* Next, try a direct socket connection. Open socket in another
* thread and only wait for specified timeout, in case the socket
* would otherwise spend minutes trying an unreachable host.
*/
final AsyncConnector connector =
// connection must be attempted with
// this thread's access control context
try {
synchronized (connector) {
t.start();
try {
do {
if (initialSocket != null)
break;
} catch (InterruptedException e) {
throw new InterruptedIOException(
"interrupted while waiting for connector");
}
}
// assume no route to host (for now) if no connection yet
if (initialSocket == null)
throw new NoRouteToHostException(
"connect timed out: " + host);
return initialSocket;
} catch (UnknownHostException | NoRouteToHostException e) {
initialFailure = e;
} catch (SocketException e) {
if (eagerHttpFallback) {
initialFailure = e;
} else {
throw e;
}
} finally {
if (initialFailure != null) {
"direct socket connection failed: ", initialFailure);
}
// Finally, try any alternate connection mechanisms.
"trying with factory: " + factory);
}
try (Socket testSocket =
// For HTTP connections, the output (POST request) must
// be sent before we verify a successful connection.
// So, sacrifice a socket for the sake of testing...
// The following sequence should verify a successful
// HTTP connection if no IOException is thrown.
} catch (IOException ex) {
}
continue;
}
// factory succeeded, open new socket for caller's use
try {
} // just give up
break;
}
}
}
synchronized (successTable) {
try {
// check once again to see if direct connection succeeded
synchronized (connector) {
}
if (initialSocket != null) {
// if we had made another one as well, clean it up...
if (fallbackSocket != null)
return initialSocket;
}
// if connector ever does get socket, it won't be used
} catch (UnknownHostException | NoRouteToHostException e) {
initialFailure = e;
} catch (SocketException e) {
if (eagerHttpFallback) {
initialFailure = e;
} else {
throw e;
}
}
// if we had found an alternate mechanism, go and use it
if (fallbackSocket != null) {
return fallbackSocket;
}
throw initialFailure;
}
}
/**
* Remember a successful factory for connecting to host.
* Currently, excess hosts are removed from the remembered list
* using a Least Recently Created strategy.
*/
synchronized (successTable) {
}
}
}
/**
* Check if an AsyncConnector succeeded. If not, return socket
* given to fall back to.
*/
throws IOException
{
if (e != null) {
e.fillInStackTrace();
/*
* The AsyncConnector implementation guaranteed that the exception
* will be either an IOException or a RuntimeException, and we can
* only throw one of those, so convince that compiler that it must
* be one of those.
*/
if (e instanceof IOException) {
throw (IOException) e;
} else if (e instanceof RuntimeException) {
throw (RuntimeException) e;
} else {
throw new Error("internal error: " +
"unexpected checked exception: " + e.toString());
}
}
}
/**
* Create a new server socket.
*/
//return new HttpAwareServerSocket(port);
}
/**
* AsyncConnector is used by RMIMasterSocketFactory to attempt socket
* connections on a separate thread. This allows RMIMasterSocketFactory
* to control how long it will wait for the connection to succeed.
*/
/** what factory to use to attempt connection */
/** the host to connect to */
/** the port to connect to */
private int port;
/** access control context to attempt connection within */
/** exception that occurred during connection, if any */
/** the connected socket, if successful */
/** socket should be closed after created, if ever */
private boolean cleanUp = false;
/**
* Create a new asynchronous connector object.
*/
{
}
}
/**
* Attempt socket connection in separate thread. If successful,
* notify master waiting,
*/
public void run() {
try {
/*
* Using the privileges of the thread that wants to make the
* connection is tempting, but it will fail with applets with
* the current applet security manager because the applet
* network connection policy is not captured in the permission
* framework of the access control context we have.
*
* java.security.AccessController.beginPrivileged(acc);
*/
try {
synchronized (this) {
notify();
}
synchronized (this) {
if (cleanUp)
try {
} catch (IOException e) {
}
}
} catch (Exception e) {
/*
* Note that the only exceptions which could actually have
* occurred here are IOException or RuntimeException.
*/
synchronized (this) {
exception = e;
notify();
}
}
} finally {
/*
* See above comments for matching beginPrivileged() call that
* is also commented out.
*
* java.security.AccessController.endPrivileged();
*/
}
}
/**
* Get exception that occurred during connection attempt, if any.
* In the current implementation, this is guaranteed to be either
* an IOException or a RuntimeException.
*/
return exception;
}
/**
* Get successful socket, if any.
*/
return socket;
}
/**
* Note that this connector's socket, if ever successfully created,
* will not be used, so it should be cleaned up quickly
*/
synchronized void notUsed() {
try {
} catch (IOException e) {
}
}
cleanUp = true;
}
}
}