Re: Clarification on firewall issues with Java networking APIs



Arne Vajhøj wrote:

Nigel Wade wrote:
Qu0ll wrote:
I understand that RMI doesn't play well with the internet because it can't
work properly when either the client or the server is behind a proxy unless
tunneling is used and that tunneling is slow and prevents callbacks from
being used. So I get it that RMI is probably not the network API for me.

RMI plays perfectly well with the Internet, but not firewalls. I think RMI
works
in a very similar way to portmapper. The rmiregistry listens on a well-known
port. A RMI server registers its service with the rmiregistry, and is either
assigned or tells the registry the port that it actually listen on. A RMI
client asks the rmiregistry for the "location" of a particular service, and
the
rmiregistry replies telling the client what host/port the server is listening
on.

For the above to work through a firewall the client must be able to connect
to
the server both on the rmiregistry port and the port on which the server is
listening. This will normally cause problems with firewalls because they are
not configured to allow this to happen for dynamic ports. It may be possible
for an RMI server to request a specific port and register that, but I'm not
certain (RMISocketFactory.createServerSocket(int port)?). That way it might
be
possible to open only the rmiregistry port and the specific RMI server ports
in
the firewall.

It is possible.

RMISocketFactory.setSocketFactory(new FixedPortRMISocketFactory());
LocateRegistry.createRegistry(60000);

and:

package test.server;

import java.io.IOException;
import java.net.Socket;
import java.net.ServerSocket;
import java.rmi.server.RMISocketFactory;

public class FixedPortRMISocketFactory extends RMISocketFactory {
private static int socketNumber = 60000;
public Socket createSocket(String host, int port) throws IOException {
return new Socket(host, port);
}
public ServerSocket createServerSocket(int port) throws IOException {
if(port == 0) {
socketNumber++;
port = socketNumber;
}
return new ServerSocket(port);
}
}

will use port 60000 for registry and 60001, 60002, ... for
server.

And I understand that servlets don't have this problem because they
communicate through the standard HTTP port but that servlets don't support
callbacks for non-HTML clients. (Feel free to disagree if appropriate).

Servlets can communicate via any port. The initial connection is made to the
servlet container on whatever port that happens to be listening on. It may be
80, or 8080 or any other port. The socket is passed to the servlet's service
routine and the servlet can send a reply on that already established socket.
There is no requirement for communication to be HTTP unless you extend
HttpServlet. A GenericServlet can use any protocol (layered over TCP/IP).

Servlets can also open any other socket they wish, including initiating
callback
to a client. If you do this in the service method you are likely to get
deadlock if the servlet attempts to initiate a new communication channel with
the client whilst the client is waiting for the servlet to respond to its
initial request. You would have to handle this carefully.

Servlet containers are not written to support long running servlets.

"Long" as in "how long is a piece of string" is a relative term... ;-)


You could also start a background thread in the servlet. The background
thread
could open a socket to the client and send data when it was ready. The client
would have to be listening to accept the connection and be able to read the
data.

Much better concept.

I have tried this specific method and failed. The thread would run perfectly for
anything between 12 to 14 days, and then die without any indication as to why
it had died. There was no output in any of the Tomcat logs, or the servlet
logs, no stack trace, and I was unable to establish any monitor which would
trap the thread's death. It just vanished without a trace. Needless to say, a
thread which runs for 12 to 14 days and then vanishes is rather hard to debug.
So I changed the design to use blocking calls.

In my case the "long" as discussed above is typically of the order of 10s, and I
use a timeout so there is no issue with the container and long running
servlets. Of course this means the client has to handle the problem of a call
returning with no data. But that's a simple matter of having the thread in the
client which reads the data loop over the call, and re-issue it if the return
status indicates a timeout.


But with this method you are at the mercy of the servlet container as it
may decide to unload the servlet if it doesn't received any new service
calls.

I think that is only theoretical.

Maybe...


The simplest method is to use blocking calls. The client makes a service
request
to the servlet as normal, but the servlet does not return until there is
something to return.

I think a non non waiting servlet and a thread is much better.

It would be if it can be made to work. Besides keeping the thread alive, you
have the problem of the servlet being able to establish a connection back to
the client through whatever firewalls are in the way.


With many requests the waiting servlets could lockup the container.

Yep, all the methods have pros and cons. These need to be weighed up in the
context of how the application will be used in practise. I don't think there is
any "one size fits all" solution to this type of problem.


--
Nigel Wade, System Administrator, Space Plasma Physics Group,
University of Leicester, Leicester, LE1 7RH, UK
E-mail : nmw@xxxxxxxxxxxx
Phone : +44 (0)116 2523548, Fax : +44 (0)116 2523555
.



Relevant Pages

  • Re: Unable to print to networked printer - get access denied messa
    ... Check the permissions on the server assuming the client has a true RPC ... How is the Standard TCP/IP port configured for the device? ...
    (microsoft.public.windowsxp.print_fax)
  • Re: interfaces lo:1 lo:2 lo:3? (for remote ssh tunnels)
    ... That's the problem tunneling (port forwarding) solves. ... >>can't get past the client firewall. ... > I don't understand why the server would be making the ... server initiates another connection to the client -- in this ...
    (Debian-User)
  • Re: Remote Connection Issue
    ... through port number 3389 and a workstation on the LAN through port number ... I understand that you want to allow a LAN client ... and you have configured server publishing rule ... > By default Terminal Server and Windows 2000 Terminal Services uses TCP ...
    (microsoft.public.windows.server.sbs)
  • Re: RealVNC
    ... Default listening port for RealVNC server that runs on the machine on which ... Then there is default Java listening port on port 5800 on the client machine ...
    (microsoft.public.windows.server.sbs)
  • Re: Redirecting data sent to a local printer to another host and port on the network
    ... All client workstations have access to the ... simply redirecting netcat traffic on port 9100 to port 515 on ... Only LPR clients talk to LPD print server daemons. ... >workstation at the branch site where the print job originated. ...
    (comp.unix.sco.misc)