Our chat client must not require the user to make any modifications to a client-side firewall. (We assume that the client-side firewall already permits outgoing connections to arbitrary servers.) In Ice, new connections are established as the result of client activity, and requests normally flow in only one direction: from the client (the originator of the connection) to the server.

In the case of a callback, the server would normally establish a separate connection back to the client:

However, a client-side firewall presents a challenge for our push model because it will block the server's attempt to establish a new connection:

We can solve this problem using Ice's bidirectional connection facility, which allows requests to flow in either direction over a client's existing connection with a server. With this facility, the chat server can make callbacks without needing to establish a new connection to the chat client:

An even better solution is to incorporate a Glacier2 router into our design. Glacier2 is an Ice service that typically resides behind a server-side firewall and securely routes requests from clients to back-end servers. A client establishes a bidirectional connection to Glacier2, which allows the router to forward callbacks from a back-end server to the client over the client's existing connection with Glacier2:

Glacier2 is used by all of the chat clients that implement the push model.