Why Java RMI Callback doesn't work behind NAT router?

728 views Asked by At

I'm trying to do callback on Java RMI with a simple program, and it works OK in localhost and LAN, but I have problems doing that behind a NAT router.

I get connection refused if my server implementation extends UnicastRemoteObject. If I don't extends UnicastRemoteObject and I export the object manually (UnicastRemoteObject.exportObject(services, 0);), the server does the action when the client calls the remote method, and when the server calls the callback method, it gets a connection timeout because call is going to the private IP.

I bind the service in the registry like this:

public class Server {
    private static final String SRVHOST = "<<external ip>>";
    private static Registry registry;

    public static void main(String[] args) {
        System.setProperty("java.rmi.server.hostname", SRVHOST);
        System.setProperty("java.rmi.server.useCodebaseOnly","false"); 
        System.setProperty("java.security.policy","src/srv.policy");

        if(System.getSecurityManager()==null)
            System.setSecurityManager(new RMISecurityManager());

        registry = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
        ServerInterface services = new ServerImpl();
        registry.rebind("ServerAPI", services);
    }
}

And client gets the service:

public class Client {
    private static final String SRVHOST = "localhost";
    private static Registry registry;
    private static ClientInterface callback;

    public static void main(String[] args) {
        System.setProperty("java.security.policy", "src/cli.policy");

        if(System.getSecurityManager()==null)
            System.setSecurityManager(new RMISecurityManager());


        registry = LocateRegistry.getRegistry(SRVHOST, Registry.REGISTRY_PORT);
        ServerInterface services = (ServerInterface) registry.lookup("ServerAPI");
        callback = new ClientImpl();
        int nCallback = services.setClientInterface(callback);
        ...
        <<do_things>>
    }
}

The method setClientInterface(...) gets the client object and stores it in an ArrayList.

I don't know what's the problem. Can someone help me?

All the code is published here:

Policy files:

srv.policy - http://pastebin.com/LTsKSG3r

cli.policy - http://pastebin.com/zqxaRyT3

Package: com.rmicallback.client

Client.java - http://pastebin.com/Xus04JZK

ClientImpl.java - http://pastebin.com/SdQXMDzs

ClientInterface.java - http://pastebin.com/S9PxT5vC

Package: com.rmicallback.server

Server.java - http://pastebin.com/cxQcWy1Q

ServerImpl.java - http://pastebin.com/nqdGPbPr

ServerInterface.java - http://pastebin.com/nPxDJgs1

0

There are 0 answers