Hello everyone,
I am trying to cut down the number of ports that must be opened in a firewall to let the client talk to the protected server. The server creates its own registry object by calling LocateRegistry.createRegistry(port), and the same port is used when UnicastRemoteObjects are exported. This way, I can tell the firewall admin to open only one hole in the firewall, instead of two.
It all works, until I attempt to use a custom socket factory for the registry (the factory explicitly sets the IP address to which the registry binds - important for the multi-homed hosts). If I set the socket factory to the registry only:
LocateRegistry.createRegistry(port, null, mySocketFactory)
and leave the exported objects to their default factory settings, I get a "port already in use" exception. If I set the same instance of the socket factory to the UnicastRemoteObjects, this is what happens:
1. The first UnicastRemoteObject exports normally and responds to the remote calls. 2. Any other UnicastRemoteObject to be exported on the same port with the same instance of the socket factory throws the same old "port already in use" exception.
What am I missing in my version of the socket factory that the default implementation has and what lets it bind multiple objects to the same port without blowing up?
Here is the source code for the socket factory:
public class RegistrySocketFactory extends RMISocketFactory implements Serializable {
private InetAddress ipInterface = null;
private static RegistrySocketFactory instance = null; // turn this class into a singleton
public RegistrySocketFactory(InetAddress ipInterface)
{
this.ipInterface = ipInterface;
instance = this;
}
public static RegistrySocketFactory getInstance()
{
return (instance);
}
public ServerSocket createServerSocket(int port)
{
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(port, 50, ipInterface);
}
catch (Exception e)
{
System.out.println(e);
}
return (serverSocket);
}
public Socket createSocket(String ipInterface, int port) throws IOException
{
Socket socket= new Socket(ipInterface, port);
return socket;
}
}
And this is the snippet of the context in which it is used:
RegistrySocketFactory socketFactory = new RegistrySocketFactory(address);
LocateRegistry.createRegistry(6541, null, socketFactory);
proxy = new Proxy(6541); // this works
proxyHook = new ProxyHook(this); // this throws "port in use" exception
public Proxy(int port) throws RemoteException
{
super(6541, null, RegistrySocketFactory.getInstance());
}
public ProxyHook(Proxy controller) throws RemoteException
{
super(6541, null, RegistrySocketFactory.getInstance());
}