Archived

This forum has been archived. Please start a new discussion on GitHub.

mission impossible?

A client behind the firewalls,
B client behind another firewalls.
How to establish an connection that A or B can invoke an operation on B or A?
mission impossible?

Comments

  • mes
    mes California
    In order for A and B to communicate, at least one of the routers would need to open a port. For example, if A's firewall opens a port, then B can establish a connection to A and invoke operations. Furthermore, if you use a bidirectional connection, then A can invoke operations on B without requiring a separate connection to B, but only as long as B is connected to A.

    Another possibility is to write a forwarding service that runs on a host that is accessible to both A and B.

    Take care,
    - Mark
  • > Another possibility is to write a forwarding service that runs on a
    > host that is accessible to both A and B.

    I'm interested in implementing a system with exactly this architecture. A and B may both be behind (different) firewalls. I'll mostly need to allow A to send messages to B and to request information from B, but there might be times when B needs to send messages to A as well. I unfortunately cannot assume that either A or B will be able to open any firewall ports. So, my first inclination is to have A and B each create bidirectional connections to the forwarding service. Or would Glacier2 be a better choice in this situation? Why or why not?

    Given a message from A, the forwarding service would first need to authenticate A to ensure it is allowed to talk to B (I need to prevent other clients, say C, from connecting to the forwarding service and attempting to send messages to A, but at the same time allow C to send messages to approved targets such as D) and then forward the request on to B. So it seems that the forwarding service will need to implement the same interface as A, but with different behavior (forwarding the message rather than actually performing the action). Or is there a way to write it more generically, so that the forwarding service doesn't need an implementation of every command, but instead has some generic authenticateAndForward() command? Am I making sense? I'd like to be able to allow users to extend the interfaces supported by A and B without having to change any code in the forwarding service, so a generic solution would be better if at all possible.

    Many thanks,

    Chris
  • xdm
    xdm La Coruña, Spain
    Hi bartley

    i don't know if this is exactly what you need but you can take a look to mathews Chat examples. in the chat clients comunicate ones with others and they can be behind firewalls and there isn't needs for open a especial port.

    you can find the first version in Newsletters issue3 with c++ sources http://www.zeroc.com/newsletter/index.html
  • Thanks, I'll have a look at the newsletters. However, although my understanding of Glacier2 is limited, wouldn't the use of Glacier2 require opening at least one firewall port? I unfortunately don't have that luxury.

    If Glacier2 is indeed not an option for me, what about the forwarding service scenario I descibed in my previous post (with bidirectional connections from A and B to the forwarding service)? Does my implementation description make sense? Is there a better approach?

    Thanks,

    Chris
  • mes
    mes California
    Chris,

    Ice does support an API that allows you to receive and send requests as "blobs" of bytes. The Glacier2 and IceStorm services use this facility to forward requests without needing application-specific knowledge. Chapter 35 in the Ice manual discusses this feature.

    The Glacier2 service is normally used as a front-end for one or more servers. Its use wouldn't require you to open ports in client firewalls. It has several advantages:
    • Bidirectional connections are handled automatically. Servers are not aware of Glacier2's presence and need no special code to manually prepare bidirectional connections.
    • Only one port needs to be opened in the server-side firewall, but any number of back-end servers can be used.
    • It supports authentication and session-based communication.
    • It has security features to prevent clients from accessing unauthorized objects.
    I strongly recommend reading up on Glacier2 to see if it can simplify your project.

    If you don't use Glacier2, you'll likely need to implement something similar to it to meet your authentication requirements.

    Take care,
    - Mark
  • Thanks, Mark, I appreciate your helpful and quick reply! :)

    I'm afraid, though, that Glacier2 might not work for my situation since I can't open any ports on any firewalls. So, it seems like I'll need the relay (a.k.a forwarding service) running on a public server. Something like this:
                                          |                 |
    
    ------------        --------------    |    ---------    |    --------------        ------------
    |          |        | Client A's |         |       |         | Client B's |        |          |
    | Client A | <----> |            | <--|--> |       | <--|--> |            | <----> | Client B |
    |          |        |  Firewall  |         |       |         |  Firewall  |        |          |
    ------------        --------------    |    |       |    |    --------------        ------------
                                               | Public|
                                          |    | Relay |    |
                                               |       |     
    ------------        --------------    |    |       |    |    --------------        ------------
    |          |        | Client C's |         |       |         | Client D's |        |          |
    | Client C | <----> |            | <--|--> |       | <--|--> |            | <----> | Client D |
    |          |        |  Firewall  |         |       |         |  Firewall  |        |          |
    ------------        --------------    |    ---------    |    --------------        ------------
    
                                          |                 |
    

    Communication will always be in pairs like this (A and B, C and D, etc.) and some authentication rule will determine whether a pairing is allowed. I'm envisioning a pairing to occur something like this:
    1. B creates a bidirectional connection to the relay and registers itself.
    2. A creates a bidirectional connection to the relay and registers itself.
    3. A requests a list of currently-connected clients that it is allowed to talk to. (there's only one in this case: B)
    4. A asks the relay to pair it with B.
    5. The relay creates the pairing so that future messages from A are routed to B. In truth, only a certain set of messages get auto-routed to B--there will be some messages from A to the relay which don't get routed because they're intended solely for the relay.

    What I'm not sure about now is whether there's any use in running Glacier2 on the forwarding server? Does that buy me anything? Or maybe two Glaciers running on the relay (talking to each other), one for each side of the pairing?

    Maybe I just need to delve into Glacier more, but the port-opening requirement seems like a killer for my (admittedly restrictive) situation. That's too bad, because it sounds like it does everything I want. Bummer. :(

    thanks heaps,

    Chris
  • mes
    mes California
    Hi,

    Glacier2 could be used in this situation as well. It's no different than any other Ice server you might write: if it's running on a public server, there's no need to perform any special firewall configuration. If you were running in a restricted environment where your servers reside behind a firewall, then Glacier2 is helpful because you only need to open a single port on the firewall, through which all of the back-end servers are accessible (via Glacier2).

    In the situation you've described, the reasons you might want to incorporate Glacier2 are authentication and security. In addition, it eliminates the need for your clients and servers to manually establish bidirectional connections, so there's a bit less code to write.

    Take care,
    - Mark
  • Thanks, Mark, for your help and patience as I try to wrap my brain around all this! :)
    In the situation you've described, the reasons you might want to incorporate Glacier2 are authentication and security. In addition, it eliminates the need for your clients and servers to manually establish bidirectional connections, so there's a bit less code to write.

    Less code sounds good to me! I'd like to clarify one point, though. In the architecture drawing in my previous post, I labeled B and D as clients. I should clarify that I called them clients just because they (must) initiate the connection to the relay server (due to their firewalls). Otherwise, it's probably more correct to consider them servers since, if I had the luxury of having both A and B behind the same firewall, then A would act as a client and send messages to B (and occasionally receive callbacks). So, my drawing was not intended to be symmetrical. That is, B and D are very different beasts than A and C (in reality, B and D are robots, whereas A and C are humans using GUIs to control the robots).

    What I'm trying to understand is how Glacier2 running on the publicly-accessible relay would work. The "server" I want it to ultimately talk to (e.g. B) is behind a firewall, so Glacier can't initiate the connection. That's a problem, no? Will Glacier need to talk to a local server (also located on the relay) which routes messages to B (assuming B has somehow previously registered itself with that local server)? If not, how do I link up B with Glacier? Am I making any sense? :o

    Thanks again,

    chris
  • mes
    mes California
    Hi,

    You are correct that Glacier2 could not establish a connection to B; B would be required to initiate the connection to your relay via Glacier2. As long as B keeps its Glacier2 session alive, the relay can forward requests to B's objects via Glacier2. These requests would travel over the bidirectional connection from B to Glacier2, so no new connection is required.

    Hope that helps,
    - Mark
  • Great, thanks for all your help. I think I finally understand it now. :)

    Off to write some code!

    thanks heaps,

    chris