13
The full OMG IDL for the DCE ESIOP specification is shown in Section 13.7, "OMG IDL for the DCE CIOP Module," on page 13-24. Fragments are used throughout this chapter as necessary.
13.2.1 DCE-CIOP RPC
DCE-CIOP requires an RPC which is interoperable with the DCE connection-oriented and/or connectionless protocols as specified in the X/Open CAE Specification C309 and the OSF AES/Distributed Computing RPC Volume. Some of the features of the DCE-RPC are as follows:
NDR is the transfer syntax used by DCE-RPC for operations defined in DCE IDL. CDR, used to represent messages defined in OMG IDL on top of DCE RPCs, represents the OMG IDL primitive types identically to the NDR representation of corresponding DCE IDL primitive types. The corresponding OMG IDL and DCE IDL primitive types are shown in table Table 13-1.
1
Restricted to IEEE format. 2 Restricted to IEEE format. 3 Values restricted to 0 and 1.
|
The CDR representation of OMG IDL constructed types and pseudo-object types does not correspond to the NDR representation of types describable in DCE IDL.
13.2.3 DCE-CIOP Messages
The following request and response messages are exchanged between ORB clients and servers via the invoke
and locate
RPCs:
The pipe-based interface is the preferred interface, since it allows messages to be transmitted without precomputing the message length. But not all DCE-RPC implementations adequately support pipes, so this interface is optional. All client and server ORBs implementing DCE-CIOP must support the array-based interface3.
While server ORBs may provide both interfaces or just the array-based interface, it is up to the client ORB to decide which to use for an invocation. If a client ORB tries to use the pipe-based interface and receives a
rpc_s_unknown_if
error, it should fall back to the array-based interface. 13.3.1 Pipe-based Interface
The dce_ciop_pipe
interface is defined by the DCE IDL specification shown below:[ /* DCE IDL */
uuid(0e07f95c-37b0-11ce-90a7-0800090b5d3e),
version(1.0)
]
interface dce_ciop_pipe
{
typedef pipe byte message_type;
void invoke ([in] handle_t binding_handle,
[in] message_type *request_message,
[out] message_type *response_message);
void locate ([in] handle_t binding_handle,
[in] message_type *request_message,
[out] message_type *response_message);
}
ORBs can implement the dce_ciop_pipe
interface by using DCE stubs generated from this IDL specification, or by using lower-level APIs provided by a particular DCE-RPC implementation.dce_ciop_pipe
interface is identified by the UUID and version number shown. To provide maximal performance, all server ORBs and location agents implementing DCE-CIOP should listen for and handle requests made to this interface. To maximize the chances of interoperating with any DCE-CIOP client, servers should listen for requests arriving via all available DCE protocol sequences.dce_ciop_pipe
interface.dce_ciop_pipe
interface is made up of two DCE-RPC operations, invoke
and locate
. The first parameter of each of these RPCs is a DCE binding handle, which identifies the server process on which to perform the RPC. See "DCE-CIOP String Binding Component" on page 13-16, "DCE-CIOP Binding Name Component" on page 13-17, and "DCE-CIOP Object Location" on page 13-21 for discussion of how these binding handles are obtained. The remaining parameters of the dce_ciop_pipe
RPCs are pipes of uninterpreted bytes. These pipes are used to convey messages encoded using CDR. The request_message
input parameters send a request message from the client to the server, while the response_message
output parameters return a response message from the server to the client.
Figure 13-1 below illustrates the layering of DCE-CIOP messages on the DCE-RPC protocol as NDR pipes:
Figure 13-1 Pipe-based interface protocol layering.
A pipe is made up of chunks, where each chunk consists of a chunk length and chunk data. The chunk length is an unsigned long indicating the number of pipe elements that make up the chunk data. The pipe elements are DCE IDL bytes, which are uninterpreted by NDR. A pipe is terminated by a chunk length of zero. The pipe chunks are concatenated to form a DCE-CIOP message.
Invoke
The invoke
RPC is used by a DCE-CIOP client process to attempt to invoke a CORBA operation in the server process identified by the binding_handle
parameter. The request_message
pipe transmits a DCE-CIOP invoke request message, encoded using CDR, from the client to the server. See "DCE_CIOP Invoke Request Message" on page 13-10 for a description of its format. The response_message
pipe transmits a DCE-CIOP invoke response message, also encoded using CDR, from the server to the client. See "DCE-CIOP Invoke Response Message" on page 13-11 for a description of the response format.
Locate
The locate
RPC is used by a DCE-CIOP client process to query the server process identified by the binding_handle
parameter for the location of the server process where requests should be sent. The request_message
and response_message
parameters are used similarly to the parameters of the invoke
RPC. See "DCE-CIOP Locate Request Message" on page 13-13 and "DCE-CIOP Locate Response Message" on page 13-14 for descriptions of their formats. Use of the locate
RPC is described in detail in "DCE-CIOP Object Location" on page 13-21.
13.3.2 Array-based Interface
The dce_ciop_array
interface is defined by the DCE IDL specification shown below:[ /* DCE IDL */
uuid(8108ae54-4cd9-11ce-acca-0800090b5d3e),
version(1.0)
]
interface dce_ciop_array
{
typedef struct {
unsigned long length;
[size_is(length),ptr] byte *data;
} message_type;
void invoke ([in] handle_t binding_handle,
[in] message_type *request_message,
[out] message_type *response_message);
void locate ([in] handle_t binding_handle,
[in] message_type *request_message,
[out] message_type *response_message);
}
ORBs can implement the dce_ciop_array
interface, identified by the UUID and version number shown, by using DCE stubs generated from this IDL specification, or by using lower-level APIs provided by a particular DCE-RPC implementation.dce_ciop_array
interface, and to maximize interoperability, should listen for requests arriving via all available DCE protocol sequences.locate
and invoke
RPCs on the dce_ciop_array
interface.dce_ciop_pipe
interface, the first parameter of each dce_ciop_array
RPC is a DCE binding handle that identifies the server process on which to perform the RPC. The remaining parameters are structures containing CDR-encoded messages. The request_message
input parameters send a request message from the client to the server, while the response_message
output parameters return a response message from the server to the client.message_type
structure used to convey messages is made up of a length
member and a data
member:
Figure 13-2 Array-based interface protocol layering.
message_type
structure. The length
member is encoded first, followed by the data
member. The data
member is a full pointer, which is represented in NDR as a referent ID. In this case, this non-NULL pointer is the first (and only) pointer to the referent, so the referent ID is 1 and it is followed by the representation of the referent. The referent is a conformant array of bytes, which is represented in NDR as an unsigned long indicating the length, followed by that number of bytes. The bytes form the DCE-CIOP message. Invoke
The invoke
RPC is used by a DCE-CIOP client process to attempt to invoke a CORBA operation in the server process identified by the binding_handle
parameter. The request_message
input parameter contains a DCE-CIOP invoke request message. The response_message
output parameter returns a DCE-CIOP invoke response message from the server to the client. Locate
The locate
RPC is used by a DCE-CIOP client process to query the server process identified by the binding_handle
parameter for the location of the server process where requests should be sent. The request_message
and response_message
parameters are used similarly to the parameters of the invoke
RPC. 13.4 DCE-CIOP Message Formats
The section defines the message formats used by DCE-CIOP. These message formats are specified in OMG IDL, are encoded using CDR, and are transmitted over DCE-RPC as either pipes or arrays of bytes as described in "DCE-CIOP Message Transport" on page 13-5.
13.4.1 DCE_CIOP Invoke Request Message
DCE-CIOP invoke request messages encode CORBA object requests, including attribute accessor operations and CORBA::Object
operations such as get_interface
and get_implementation
. Invoke requests are passed from client to server as the request_message
parameter of an invoke
RPC. Invoke Request Header
DCE-CIOP request headers have the following structure: struct InvokeRequestHeader {
boolean byte_order;
IOP::ServiceContextList service_context;
sequence <octet> object_key;
string endpoint_id;
string operation;
CORBA::Principal principal;
sequence <string> client_context;
// in and inout parameters follow
};
};
-
operation name is "_interface"
-
operation name is "_implementation"
-
operation name is "_is_a"
BOA::get_principal
operation.
response_message
parameter of an invoke
RPC.Like invoke request messages, an invoke response message is made up of a header and a body. The header has a fixed format, while the format of the body depends on the operation's OMG IDL definition and the outcome of the invocation.
module DCE_CIOP { // IDL
enum InvokeResponseStatus {
INVOKE_NO_EXCEPTION,
INVOKE_USER_EXCEPTION,
INVOKE_SYSTEM_EXCEPTION,
INVOKE_LOCATION_FORWARD,
INVOKE_TRY_AGAIN
};
struct InvokeResponseHeader {
boolean byte_order;
IOP::ServiceContextList service_context;
InvokeResponseStatus status;
// if status = INVOKE_NO_EXCEPTION,
// result then inouts and outs follow
// if status = INVOKE_USER_EXCEPTION or
// INVOKE_SYSTEM_EXCEPTION, an exception follows
// if status = INVOKE_LOCATION_FORWARD, an
// IOP::MultipleComponentsProfile follows
};};
The members have the following definitions:
status
member of the invoke response header, as well as the OMG IDL definition of the operation being invoked. Its format is one of the following:
INVOKE_NO_EXCEPTION
, then the body contains the operation result value (if any), followed by all inout and out parameters, in the order in which they appear in the operation signature, from left to right.
status
value is INVOKE_USER_EXCEPTION
or INVOKE_SYSTEM_EXCEPTION
, then the body contains the exception, encoded as in GIOP.
status
value is INVOKE_LOCATION_FORWARD
, then the body contains a new MultipleComponentProfile structure containing components that can be used to communicate with the object specified in the invoke request message. This profile must provide at least one new DCE-CIOP binding component. The client ORB is responsible for re-sending the request to the server identified by the new profile. This operation should be transparent to the client program making the request. See "DCE-CIOP Object Location" on page 13-21 for more details.
status
value is INVOKE_TRY_AGAIN
, then the body is empty and the client should reissue the invoke
RPC, possibly after a short delay5.
request_message
parameter of a locate
RPC, to determine the following regarding a specified object reference:
locate
RPC, see "DCE-CIOP Object Location" on page 13-21.
Locate request messages contain a fixed-format header, but no body.
Locate Request Header
DCE-CIOP locate request headers have the following format: struct LocateRequestHeader {
boolean byte_order;
sequence <octet> object_key;
string endpoint_id;
string operation;
// no body follows
};
};
response_message
parameter of a locate
RPC. They consist of a fixed-format header, and a body whose format depends on information in the header.
module DCE_CIOP { // IDL
enum LocateResponseStatus {
LOCATE_UNKNOWN_OBJECT,
LOCATE_OBJECT_HERE,
LOCATE_LOCATION_FORWARD,
LOCATE_TRY_AGAIN
};
struct LocateResponseHeader {
boolean byte_order;
LocateResponseStatus status;
// if status = LOCATE_LOCATION_FORWARD, an
// IOP::MultipleComponentProfile follows
};};
The members have the following definitions:
status
member of the locate response header. Its format is one of the following:
status
value is LOCATE_UNKNOWN_OBJECT
, then the object specified in the corresponding locate request message is unknown to the server. The locate reply body is empty in this case.
status
value is LOCATE_OBJECT_HERE
, then this server (the originator of the locate response message) can directly receive requests for the specified object. The locate response body is also empty in this case.
status
value is LOCATE_LOCATION_FORWARD
, then the locate response body contains a new MultipleComponentProfile structure containing components that can be used to communicate with the object specified in the locate request message. This profile must provide at least one new DCE-CIOP binding component.
LOCATE_TRY_AGAIN
, the locate response body is empty and the client should reissue the locate
RPC, possibly after a short delay6.
profile_data
for this profile is a CDR encapsulation of the MultipleComponentProfile type, which is a sequence of TaggedComponent structures. These types are described in "An Information Model for Object References" on page 10-14.
DCE-CIOP defines a number of IOR components that can be included in a MultipleComponentProfile. Each is identified by a unique tag, and the encoding and semantics of the associated component_data are specified.
13.5.1 DCE-CIOP String Binding Component
A DCE-CIOP string binding component, identified by TAG_DCE_STRING_BINDING, contains a fully or partially bound string binding. A string binding provides the information necessary for DCE-RPC to establish communication with a server process that can either service the client's requests itself, or provide the location of another process that can. The DCE API routine rpc_binding_from_string_binding
can be used to convert a string binding to the DCE binding handle required to communicate with a server as described in "DCE-CIOP Message Transport" on page 13-5.
This component is intended to be used only by DCE-CIOP. At least one string binding or binding name component must be present for an IOR profile to support DCE-CIOP.
const IOP::ComponentId TAG_DCE_STRING_BINDING = 100;
};tag
member to TAG_DCE_STRING_BINDING, and setting the component_data member to the value of a DCE string binding. The string is represented directly in the sequence of octets, including the terminating NUL, without further encoding. rpc_binding_from_string_binding
converts a string binding into a binding handle that can be used by a client ORB as the first parameter to the invoke
and locate
RPCs.
A partially bound string binding does not contain an endpoint. Since the DCE-RPC runtime uses an endpoint mapper to complete a partial binding, and multiple ORB servers might be located on the same host, partially bound string bindings must contain object UUIDs to distinguish different endpoints at the same network address.
This component is intended for use only by DCE-CIOP. Multiple binding name components can be included to identify multiple servers or agents capable of handling a request. At least one binding name or string binding component must be present for a profile to support DCE-CIOP.
The binding name component is defined by the following OMG IDL:
module DCE_CIOP { // IDL
const IOP::ComponentId TAG_DCE_BINDING_NAME = 101;
struct BindingNameComponent {
unsigned long entry_name_syntax;
string entry_name;
string object_uuid;
};};
A TaggedComponent structure is built for the binding name component by setting the
tag
member to TAG_DCE_BINDING_NAME, and setting the component_data member to a CDR encapsulation of a BindingNameComponent structure.
rpc_ns_binding_import_*
or rpc_ns_binding_lookup_*
families of DCE API routines to obtain binding handles to communicate with a server. If the object_uuid
member is an empty string, a nil object UUID should be passed to these DCE API routines.
dce_ciop_pipe
DCE-RPC interface. It is only a hint, and can be safely ignored. As described in "DCE-CIOP Message Transport" on page 13-5, the client must fall back to the array-based interface if the pipe-based interface is not available in the server.
module DCE_CIOP {
const IOP::ComponentId TAG_DCE_NO_PIPES = 102;
};tag
member of TAG_DCE_NO_PIPES must have an empty component_data member. 13.5.4 Object Key Component
An ORB server must include a single object key component, identified by TAG_OBJECT_KEY, in a DCE-CIOP IOR profile to hold the data it uses to identify the object. Its component_data value is used as the object_key member in invoke and locate request message headers. const ComponentId TAG_OBJECT_KEY = 10;
};
13.5.5 Endpoint ID Component
An optional endpoint ID component can be included in IOR profiles to enable client ORBs to minimize resource utilization and to avoid redundant locate messages. It can be used by other protocols as well as by DCE-CIOP. No more than one endpoint ID component should be included in a profile. const ComponentId TAG_ENDPOINT_ID = 11;
};
The endpoint ID component, if present in the IOR profile, is included in invoke and locate request message headers as the endpoint_id member. The server or agent can use the endpoint ID in conjunction with the object key to identify the object and its implementation. If no endpoint ID is included in the profile, an empty string is used as the
endpoint_id
member of the request messages. 13.5.6 Location Policy Component
An optional location policy component can be included in IOR profiles to specify when a DCE-CIOP client ORB should perform a locate
RPC before attempting to perform an invoke
RPC. No more than one location policy component should be included in a profile, and it can be used by other protocols that have location algorithms similar to DCE-CIOP. const ComponentId TAG_LOCATION_POLICY = 12;
const octet LOCATE_NEVER = 0;
const octet LOCATE_OBJECT = 1;
const octet LOCATE_OPERATION = 2;
const octet LOCATE_ALWAYS = 3;
};tag
member to TAG_LOCATION_POLICY, and setting the component_data member to a sequence containing a single octet, whose value is LOCATE_NEVER, LOCATE_OBJECT, LOCATE_OPERATION, or LOCATE_ALWAYS.
invoke
RPC. No locate
RPC is necessary.
locate
RPC once per object. The operation
member of the locate request message will be ignored.
locate
RPC for each distinct operation on the object. This policy can be used when different methods of an object are located in different processes.
locate
RPC for each invocation on the object. This policy can be used to support server-per-method activation.
locate
RPCs and to avoid invoke
RPCs that return INVOKE_LOCATION_FORWARD status. It is not needed to provide correct semantics, and can be ignored. Even when this hint is utilized, an invoke
RPC might result in an INVOKE_LOCATION_FORWARD response. See "DCE-CIOP Object Location" on page 13-21 for more detail.
A client does not need to implement all location policies to make use of this hint. A location policy with a higher value can be substituted for one with a lower value. For instance, a client might treat LOCATE_OPERATION as LOCATE_ALWAYS to avoid having to keep track of binding information for each operation on an object.
locate
RPC for the first object with a particular endpoint ID, and then just perform an invoke
RPC for other objects with the same endpoint ID. When a location policy of LOCATE_NEVER is combined with an endpoint ID component, only invoke
RPCs need be performed. The LOCATE_ALWAYS and LOCATE_OPERATION policies should not be combined with an endpoint ID component in a profile. 13.6 DCE-CIOP Object Location
This section describes how DCE-CIOP client ORBs locate the server ORBs that can perform operations on an object via the invoke
RPC. 13.6.1 Location Mechanism Overview
DCE-CIOP is defined to support object migration and location services without dictating the existence of specific ORB architectures or features. The protocol features are based on the following observations:
Client ORBs must, however, be able to accept and process invoke response messages with INVOKE_LOCATION_FORWARD status, since any server ORB may choose to implement a location service. Whether a client ORB chooses to send locate request messages is at the discretion of the client.
Client ORBs that send locate request messages can use the location policy component found in DCE-CIOP IOR profiles to decide whether to send a locate request message before sending an invoke request message. See "Location Policy Component" on page 13-20. This hint can be safely ignored by a client ORB.
A client should not make any assumptions about the longevity of addresses returned by location forwarding mechanisms. If a binding handle based on location forwarding information is used successfully, but then fails, subsequent attempts to send requests to the same object should start with the original address specified in the object reference.
13.6.2 Activation
Activation of ORB servers is transparent to ORB clients using DCE-CIOP. Unless an IOR refers to a transient object, the agent addressed by the IOR profile should either be permanently active, or should be activated on demand by DCE's endpoint mapper. 13.6.3 Basic Location Algorithm
ORB clients can use the following algorithm to locate the server capable of handling the invoke
RPC for a particular operation:
invoke
RPC might return INVOKE_LOCATION_FORWARD, in which case the client ORB should make the returned MultipleComponentProfile structure the current profile, and re-enter the location algorithm at step 2.If an RPC on a binding handle fails after it has been used successfully, the client ORB should start over at step 1.
Note that the TAG_OBJECT_KEY and TAG_ENDPOINT_ID components for all
invoke
and locate
RPCs are taken from the original profile. These components should not be included in the MultipleComponentProfile structure returned in INVOKE_LOCATION_FORWARD and LOCATE_LOCATION_FORWARD response messages. Only the TAG_DCE_STRING_BINDING and TAG_DCE_BINDING_NAME components, and possibly the optional TAG_LOCATION_POLICY and TAG_DCE_NO_PIPES components are taken from the current profile.
locate
RPCs may be performed, and invoke
RPCs may be performed when locate
RPCs would be more efficient. The optional location policy and endpoint ID components can be used by the client ORB, if present in the IOR profile, to optimize this algorithm.
locate
RPC or an invoke
RPC in step 3 based on the location policy of the current IOR profile. If the current profile has a TAG_LOCATION_POLICY component with a value of LOCATE_NEVER, the client should perform an invoke
RPC. Otherwise, it should perform a locate
RPC.
component_data
value. The client only needs to perform the location algorithm once per endpoint.An endpoint ID component should never be combined in the same profile with a location policy of LOCATE_OPERATION or LOCATE_ALWAYS.
module DCE_CIOP {
struct InvokeRequestHeader {
boolean byte_order;
IOP::ServiceContextList service_context;
sequence <octet> object_key;
string endpoint_id;
string operation;
CORBA::Principal principal;
sequence <string> client_context;
// in and inout parameters follow
};module DCE_CIOP {
enum InvokeResponseStatus {
INVOKE_NO_EXCEPTION,
INVOKE_USER_EXCEPTION,
INVOKE_SYSTEM_EXCEPTION,
INVOKE_LOCATION_FORWARD,
INVOKE_TRY_AGAIN
};
struct InvokeResponseHeader {
boolean byte_order;
IOP::ServiceContextList service_context;
InvokeResponseStatus status;
// if status = INVOKE_NO_EXCEPTION,
// result then inouts and outs follow
// if status = INVOKE_USER_EXCEPTION or
// INVOKE_SYSTEM_EXCEPTION, an exception follows
// if status = INVOKE_LOCATION_FORWARD, an
// IOP::MultipleComponentsProfile follows
};module DCE_CIOP {
struct LocateRequestHeader {
boolean byte_order;
sequence <octet> object_key;
string endpoint_id;
string operation;
// no body follows
};
module IOP {
const ComponentId TAG_OBJECT_KEY = 10;
const ComponentId TAG_ENDPOINT_ID = 11;
const ComponentId TAG_LOCATION_POLICY = 12;
const octet LOCATE_NEVER = 0;
const octet LOCATE_OBJECT = 1;
const octet LOCATE_OPERATION = 2;
const octet LOCATE_ALWAYS = 3;
};
CAE Specification C309 X/Open DCE: Remote Procedure Call, X/Open Company Limited, Reading, UK
2 The deferred synchronous DII API can be implemented on top of synchronous RPCs by using threads.
3 A future DCE-CIOP revision may eliminate the array-based interface and require support of the pipe-based interface.
4 The use of authentication, or other DCE security services, has not yet been defined for DCE-CIOP.
5 An exponential back-off algorithm is recommended, but not required.
6 An exponential back-off algorithm is recommended, but not required.
pubs@omg.org Copyright © 1995, Object Management Group. All rights reserved.