VisiBroker for C++ Developer’s Guide : Bidirectional Communication

Bidirectional Communication
This section explains how to establish bidirectional connections in VisiBroker without using the GateKeeper. For information about bidirectional communications when using GateKeeper, see the VisiBroker GateKeeper Guide.
Note
Before enabling bidirectional IIOP, read about “Security considerations”.
Using bidirectional IIOP
Most clients and servers that exchange information by way of the Internet are typically protected by corporate firewalls. In systems where requests are initiated only by the clients, the presence of firewalls is usually transparent to the clients. However, there are cases where clients need information asynchronously, that is, information must arrive that is not in response to a request. Client-side firewalls prevent servers from initiating connections back to clients. Therefore, if a client is to receive asynchronous information, it usually requires additional configuration.
In earlier versions of IIOP and VisiBroker, the only way to make it possible for a server to send asynchronous information to a client was to use a client-side GateKeeper to handle the callbacks from the server.
If you use bidirectional IIOP, rather than having servers open separate connections to clients when asynchronous information needs to be transmitted back to clients (these would be rejected by client-side firewalls anyway), servers use the client-initiated connections to transmit information to clients. The CORBA specification also adds a new policy to portably control this feature.
Because bidirectional IIOP allows callbacks to be set up without a GateKeeper, it greatly facilitates deployment of clients.
Bidirectional VisiBroker ORB properties
The following properties provide bidirectional support:
enableBiDir property
The vbroker.orb.enableBiDir property can be used on both the server and the client to enable bidirectional communication. This property allows you to change an existing unidirectional application into a bidirectional one without changing any code. The following table describes the vbroker.orb.enableBiDir property value options:
Enables bidirectional IIOP for all POAs and for all outgoing connections. This setting is equivalent to creating all POAs with a setting of the BiDirectional policy to both and setting the policy override for the BiDirectional policy to both on the VisiBroker ORB level. Furthermore, all created SCMs will permit bidirectional connections, as if the exportBiDir property had been set to true for every SCM.
Sets the property to both client and server.
exportBiDir property
The vbroker.se.<sename>.scm.<scmname>.manager.exportBiDir property is a client-side property. By default, it is not set to anything by the VisiBroker ORB.
Setting it to true enables creation of a bidirectional callback POA on the specified server engine.
Setting it to false disables creation of a bidirectional POA on the specified server engine.
importBiDir property
The vbroker.se.<se-name>.scm.<scm-name>.manager.importBiDir property is a server-side property. By default, it is not set to anything by the VisiBroker ORB.
Setting it to true allows the server-side to reuse the connection already established by the client for sending requests to the client.
Setting it to false prevents reuse of connections in this fashion.
Note
These properties are evaluated only once - when the SCMs are created. In all cases, the exportBiDir and importBiDir properties on the SCMs govern the enableBiDir property. In other words, if both properties are set to conflicting values, the SCM-specific properties take effect. This allows you to set the enableBiDir property globally and specifically turn off BiDir in individual SCMs.
About the BiDirectional examples
Examples demonstrating use of this feature are installed as part of your VisiBroker distribution in subdirectories in the following location:
<install_dir>\examples\vbe\bidir-iiop
All the examples are based on a simple stock quote callback application:
1
2
3
In the sections that follow, these examples are used to explain different aspects of the bidirectional IIOP feature.
Enabling bidirectional IIOP for existing applications
You can enable bidirectional communication in existing VisiBroker for Java and C++ applications without modifying any source code. A simple callback application that does not use bidirectional IIOP at all is located in the following directory:
<install_dir>\examples\vbe\bidir-iiop\basic
To enable bidirectional IIOP for the callback example, you set the vbroker.orb.enableBiDir property as follows:
1
2
UNIX
prompt> -Dvbroker.orb.enableBiDir=server Server &
Windows
prompt> start -Dvbroker.orb.enableBiDir=server Server
3
prompt> -Dvbroker.orb.enableBiDir=client RegularClient
The existing callback application now uses bidirectional IIOP and works through a client-side firewall.
Explicitly enabling bidirectional IIOP
The client in directory <install_dir>\examples\vbe\bidir-iiop\basic is derived from the RegularClient described in “Enabling bidirectional IIOP for existing applications”, except that this client enables bidirectional IIOP programmatically.
The changes required are in the client code only. To convert the unidirectional client into a bidirectional client, all you need to do is:
1
2
3
Set the exportBiDir property to true in the client.
In the following code sample, the code that implements bidirectional IIOP is displayed in bold:
try {

CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

// Get the manager Id
PortableServer::ObjectId_var managerId =
PortableServer::string_to_ObjectId("BankManager");
PortableServer::ObjectId_var oid =
PortableServer::string_to_ObjectId("QuoteServer");

Quote::QuoteServer_var quoter =
Quote::QuoteServer::_bind("/QuoteServer_poa", oid);

// set up the callback object... first get the RootPOA
CORBA::Object_var obj =
orb->resolve_initial_references("RootPOA");
PortableServer::POA_var rootPOA =
PortableServer::POA::_narrow(obj);
PortableServer::POAManager_var the_manager =
rootPOA->the_POAManager();
PortableServer::POA_var consumer_poa;

// Set up a policy.
CORBA::Any policy_value;
policy_value <<= BiDirPolicy::BOTH;
CORBA::Policy_var policy =
orb->create_policy(
BiDirPolicy::BIDIRECTIONAL_POLICY_TYPE,
policy_value);
CORBA::PolicyList policies;
policies.length(1);
policies[0] = CORBA::Policy::_duplicate(policy);
consumer_poa = rootPOA->create_POA(
"QuoteConsumer_poa", the_manager, policies );
QuoteConsumerImpl* consumer = new QuoteConsumerImpl;
oid = PortableServer::string_to_ObjectId("consumer");
consumer_poa->activate_object_with_id(oid, consumer);
the_manager->activate();
CORBA::Object_var obj =
quoter->set_policy_overrides(policies, CORBA::ADD_OVERRIDE);
quoter = Quote::QuoteServer::_narrow(obj);
obj = consumer_poa->id_to_reference(oid);
Quote::QuoteConsumer_var quote_consumer =
Quote::QuoteConsumer::_narrow(obj);
quoter->registerConsumer(quote_consumer.in());
cout << "implementation is running" << endl;
orb->run();
}
catch(const CORBA::Exception& e) {
cout << e << endl;
}
Unidirectional or bidirectional connections
A client connection can be either unidirectional or bidirectional. A server can use a bidirectional connection to call back the client without opening a new connection. Otherwise, the connection is considered unidirectional.
Enabling bidirectional IIOP for POAs
The POA on which the callback object is hosted must enable bidirectional IIOP by setting the BiDirectional policy to BOTH. This POA must be created on an SCM which has been enabled for bidirectional support by setting the vbroker.<sename>.scm.<scmname>.manager.exportBiDir property on the SCM manager. Otherwise, the POA will not be able to receive requests from the server over a client-initiated connection.
If a POA does not specify the BiDirectional policy, it must not be exposed in outgoing connections. To satisfy this requirement, a POA which does not have the BiDirectional policy set cannot be created on a server engine which has even one SCM whose exportBiDir property is set. If an attempt is made to create a POA on a unidirectional SE, an InvalidPolicy exception is raised, with the ServerEnginePolicy in error.
Note
Different objects using the same client connection may set conflicting overrides for the BiDirectional policy. Nevertheless, once a connection is made bidirectional, it always remains bidirectional, regardless of the policy effective at a later time.
Once you have full control over the bidirectional configuration, you enable bidirectional IIOP on the iiop_tp SCM only:
prompt> -Dvbroker.se.iiop_tp.scm.iiop_tp.manager.exportBiDir=
true Client
Security considerations
Use of bidirectional IIOP may raise significant security issues. In the absence of other security mechanisms, a malicious client may claim that its connection is bidirectional for use with any host and port it chooses. In particular, a client may specify the host and port of security-sensitive objects not even resident on its host. In the absence of other security mechanisms, a server that has accepted an incoming connection has no way to discover the identity or verify the integrity of the client that initiated the connection. Further, the server might gain access to other objects accessible through the bidirectional connection. This is why use of a separate, bidirectional SCM for callback objects is encouraged. If there are any doubts as to the integrity of the client, it is recommended that bidirectional IIOP not be used.
For security reasons, a server running VisiBroker will not use bidirectional IIOP unless explicitly configured to do so. The property vbroker.<se>.<sename>.scm.<scmname>.manager.importBiDir gives you control of bidirectionality on a per-SCM basis. For example, you might choose to enable bidirectional IIOP only on a server engine that uses SSL to authenticate the client, and to not make other, regular IIOP connections available for bidirectional use. (See “Bidirectional VisiBroker ORB properties” for more information.) In addition, on the client-side, you might want to enable bidirectional connections only to those servers that do callbacks outside of the client firewall. To establish a high degree of security between the client and server, you should use SSL with mutual authentication (set vbroker.security.peerAuthenticationMode to REQUIRE_AND_TRUST on both the client and server).