summaryrefslogtreecommitdiff
path: root/TAO/tao/GIOP.h
blob: 55f3e2e589f4fe5eaf0f98d0d23500fcd7bc87da (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
// This may look like C, but it's really -*- C++ -*-
// $Id$

// ============================================================================
//
// = LIBRARY
//    TAO
//
// = FILENAME
//    Giop.h
//
// = DESCRIPTION
//     GIOP data structures and support routines
//
//     Note that some symbols in this module are part of the
//     "Internet" Inter-ORB Protocol (IIOP), not the General IOP.
//     Only addressing information and certain details of connection
//     usage are specific to IIOP; all other protocol details can be
//     reused by ORB protocols that are built atop connection
//     protocols other than TCP.
//
//     THREADING NOTE: Threads should never manipulate another
//     thread's invocations.  In this implementation, all data
//     structures used to represent invocations (and parts of them)
//     are owned by the thread which created them.  Multiple threads
//     may make of course concurrent invocations safely, since the
//     GIOP code is reentrant.
//
// = AUTHOR
//     Copyright 1994-1995 by Sun Microsystems Inc.,
//     Chris Cleeland <cleeland@cs.wustl.edu>
//
// ============================================================================

#ifndef TAO_GIOP_H
#define TAO_GIOP_H

#include "tao/corbafwd.h"

#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

#include "tao/Sequence.h"
#include "tao/CDR.h"
#include "tao/IOPC.h"

class TAO_Transport;
class TAO_ORB_Core;

// namespace TAO_IOP

// Assigned Protocol/Profile tag values.  ORB protcols may be uniquely
// identified by tags such as these.  This allows each ORB's own
// objref profiles to be interchanged using IORs.
//
// Email to tag-request@omg.org to allocate tags.
typedef CORBA::ULong TAO_IOP_Profile_ID;

enum
{
  TAO_IOP_TAG_INVALID = -1,
  TAO_IOP_TAG_INTERNET_IOP = 0,                // IIOP
  TAO_IOP_TAG_MULTIPLE_COMPONENTS = 1,         // DCE-CIOP
  TAO_IOP_TAG_UNIX_IOP = TAO_TAG_UIOP_PROFILE, // Read corbafwd.h

  // = This is a subset of the list of other profile tags.
  TAO_IOP_TAG_ONC_IOP = 0x4f4e4300     // ONC IOP
};

class TAO_IOP_Tagged_Profile
{
  // = TITLE
  //   One per protocol.
public:
  TAO_IOP_Profile_ID tag;
  TAO_opaque profile_data;
};

typedef TAO_Unbounded_Sequence<TAO_IOP_Tagged_Profile>
        TAO_IOP_Tagged_Profile_Sequence;

class TAO_IOP_IOR
{
  // = TITLE
  //   InteroperableObjectReference
  //
  // = DESCRIPTION
  //   ... a set of protocol-specific protocol profiles, plus a type
  //   ID.  Only one object is denoted by all of this information.
  //   It's OK to delete all profiles except the one for the single
  //   protocol actually being used.

public:
  char *type_id;
  TAO_IOP_Tagged_Profile_Sequence profiles;
};

// Some protocols can be factored into a set of optional components.
// Use of such components is defined by the protocol's specification.
//
// Email to tag-request@omg.org to allocate tags.

typedef CORBA::ULong TAO_IOP_ComponentId;

enum
{
  // = DESCRIPTION
  //   These are all defined by DCE-CIOP in OMG TC document 95-3-10.

  TAO_IOP_TAG_DCE_STRING_BINDING = 100,// string binding handle
  TAO_IOP_TAG_DCE_BINDING_NAME = 101, // CDS/GDS/... name
  TAO_IOP_TAG_DCE_NO_PIPES = 102, // no component data
  TAO_IOP_TAG_OBJECT_KEY = 10,  // opaque
  TAO_IOP_TAG_ENDPOINT_ID = 11, // uuid
  TAO_IOP_TAG_LOCATION_POLICY = 12 // octet/enum
};

class TAO_IOP_TaggedComponent
{
  // = DESCRIPTION
  //   One way to represent multicomponent profiles, e.g. as done by
  //   the DCE-CIOP protocol.  One of these gets encapsulated in
  //   Tagged_Profile::profile_data.  TAG_MULTIPLE_COMPONENTS may be
  //   used to represent protocol profiles structured in that way, but
  //   protocol-specific tags facilitate simpler scanning of IORs
  //   since you can be assured that each profile only has data used
  //   within a single ORB protocol.
public:

  TAO_IOP_ComponentId tag;
  TAO_opaque component_data;
};

// ****************************************************************

typedef TAO_Unbounded_Sequence<TAO_IOP_TaggedComponent>
        TAO_IOP_MultipleComponentProfile;

class TAO_Export TAO_GIOP_Version
{
  // = TITLE
  //   Major and Minor version number of the Inter-ORB Protocol.
public:
  CORBA::Octet major;
  // Major version number

  CORBA::Octet minor;
  // Minor version number

  TAO_GIOP_Version (const TAO_GIOP_Version &src);
  // Copy constructor

  TAO_GIOP_Version (CORBA::Octet maj = TAO_DEF_GIOP_MAJOR,
                    CORBA::Octet min = TAO_DEF_GIOP_MINOR);
  // Default constructor.

  ~TAO_GIOP_Version (void);
  // Destructor.

  void set_version (CORBA::Octet maj, CORBA::Octet min);
  // Explicitly set the major and minor version.

  TAO_GIOP_Version &operator= (const TAO_GIOP_Version &src);
  // Copy operator.

  int operator== (const TAO_GIOP_Version &src);
  int operator!= (const TAO_GIOP_Version &src);
  // Equality operator
};

// ****************************************************************

class TAO_Export TAO_GIOP_Message_State
{
  // = TITLE
  //   Represent the state of an incoming GIOP message.
  //
  // = DESCRIPTION
  //   As the ORB processes a GIOP messages it needs to keep track of
  //   how much of the message has been read, if there are any
  //   fragments following this message, the contents of the header,
  //   etc.
  //   Notice that it is not a direct mapping from the
  //   GIOP::MessageHeader IDL structure, for example, the message
  //   flags introduced in GIOP 1.1 are expanded in several fields.

public:
  TAO_GIOP_Message_State (TAO_ORB_Core* orb_core);
  // Constructor.
  // The parameters are used to initialize the InputCDR stream

  void reset (int reset_contents = 1);
  // Reset the message header state and prepare it to receive the next
  // event.
  // already read.
  // This method will reset the header to indicate that the last
  // message was procesno data (not
  // event the

  int header_received (void) const;
  // Has the header been received?

  int is_complete (void);
  // Check if the current message is complete, adjusting the fragments
  // if required...

  // = The GIOP header for the current fragment...
  CORBA::Octet magic [4];        // "GIOP"
  TAO_GIOP_Version giop_version; // 1.1 or 1.0
  CORBA::Octet byte_order;       // 0 = big, 1 = little
  CORBA::Octet more_fragments;   // For GIOP 1.1 (Requests and Replys)
  CORBA::Octet message_type;     // MsgType above
  CORBA::ULong message_size;     // in byte_order!

  CORBA::ULong current_offset;
  // How much of the payload has been received

  TAO_InputCDR cdr;
  // This is the InputCDR that will be used to decode the message.

  ACE_Message_Block* fragments_begin;
  ACE_Message_Block* fragments_end;
  // The fragments are collected in a chain of message blocks (using
  // the cont() field).  When the complete message is received the
  // chain is reassembled into <cdr>

  CORBA::Octet first_fragment_byte_order;
  // The byte order for the the first fragment
  // @@ The current implementation cannot handle fragments with
  //    different byte orders, this should not be a major problem
  //    because:
  //    1) It is unlikely that we are going to receive fragments.
  //    2) The spec *seems* to allow different byte_orders, but it is
  //       unlikely that any ORB will do that.
  //    3) Even if we allowed that at this layer the CDR classes are
  //       not prepared to handle that.

  TAO_GIOP_Version first_fragment_giop_version;
  // The GIOP version for the first fragment
  // @@ Same as above, all GIOP versions must match.

  CORBA::Octet first_fragment_message_type;
  // If the messages are chained this represents the message type for
  // the *complete* message (remember that the last message will be
  // fragment and the upper level needs to know if it is a request,
  // locate request or what).

private:
  int append_fragment (ACE_Message_Block* current);
  // Append <current> to the list of fragments
  // Also resets the state, because the current message was consumed.
};

// The GIOP message header size
#define TAO_GIOP_HEADER_LEN 12

// The offset the message_size field inside the GIOP HEADER
#define TAO_GIOP_VERSION_MAJOR_OFFSET 4
#define TAO_GIOP_VERSION_MINOR_OFFSET 5
#define TAO_GIOP_MESSAGE_FLAGS_OFFSET 6
#define TAO_GIOP_MESSAGE_TYPE_OFFSET 7
#define TAO_GIOP_MESSAGE_SIZE_OFFSET 8

// The IIOP Lite header length and the offset of the message size
// field in it.
#define TAO_GIOP_LITE_HEADER_LEN 5
#define TAO_GIOP_LITE_MESSAGE_SIZE_OFFSET 0
#define TAO_GIOP_LITE_MESSAGE_TYPE_OFFSET 4

#if 0
// Support for Implicit ORB Service Context.
typedef CORBA::ULong TAO_GIOP_ServiceID;

enum
{
  // = TITLE
  //   Values for TAO_GIOP_ServiceID.

  TAO_GIOP_TransactionService = 0

  // More service IDs may be defined by OMG.
  // This is where our RIOP service ID will be defined...
};

// namespace TAO_GIOP

class TAO_GIOP_ServiceContext
{
  // = TITLE
  //   Sent for service context entries in the GIOP request header.
public:
  TAO_GIOP_ServiceID context_id;
  TAO_opaque context_data;
};

typedef TAO_Unbounded_Sequence<TAO_GIOP_ServiceContext>
        TAO_GIOP_ServiceContextList;

extern CORBA::TypeCode_ptr TC_ServiceContextList;

extern TAO_Export CORBA::Boolean
operator<< (TAO_OutputCDR&, const TAO_GIOP_ServiceContext&);

extern TAO_Export CORBA::Boolean
operator>> (TAO_InputCDR&, TAO_GIOP_ServiceContext&);

extern TAO_Export CORBA::Boolean
operator<< (TAO_OutputCDR&, const TAO_GIOP_ServiceContextList&);

extern TAO_Export CORBA::Boolean
operator>> (TAO_InputCDR&, TAO_GIOP_ServiceContextList&);
#endif /* 0 */

// = Reply headers

enum TAO_GIOP_ReplyStatusType
{
  TAO_GIOP_NO_EXCEPTION,
  // Request completed successfully

  TAO_GIOP_USER_EXCEPTION,
  // Request terminated with user exception

  TAO_GIOP_SYSTEM_EXCEPTION,
  // Request terminated with system exception

  TAO_GIOP_LOCATION_FORWARD
  // Reply is a location forward type
};

class TAO_GIOP_ReplyHeader
{
  // = TITLE
  //   This class embodies the header of a GIOP reply.
public:
  IOP::ServiceContextList service_info;
  // Information

  CORBA::ULong request_id;
  // Unique identifier of the request for which this is a reply.

  TAO_GIOP_ReplyStatusType reply_status;
  // Status of the reply (see above enum).
};

class TAO_GIOP_CancelRequestHeader
{
  // = TITLE
  //   Cancellation -- applies both to Requests and LocateRequests.
public:
  CORBA::ULong request_id;
  // Unique identifier of the request being cancelled
};

class TAO_GIOP_LocateRequestHeader
{
  // = TITLE
  //   Location service support
public:
  TAO_GIOP_LocateRequestHeader (void);
  // Constructor

  void init (TAO_InputCDR &msg,
             CORBA_Environment &ACE_TRY_ENV =
                 TAO_default_environment ());
  // Initialize the header from the values found in <msg>.

  CORBA::ULong request_id;
  TAO_opaque object_key;
};

enum TAO_GIOP_LocateStatusType
{
  TAO_GIOP_UNKNOWN_OBJECT,
  TAO_GIOP_OBJECT_HERE,
  TAO_GIOP_OBJECT_FORWARD
};

class TAO_GIOP_LocateReplyHeader
{
  // = TITLE
  //   Location reply.
public:
  CORBA::ULong request_id;
  TAO_GIOP_LocateStatusType locate_status;
};

class TAO_Export TAO_GIOP
{
  // = TITLE
  //   A namespace for GIOP-related operations.
  //
  // = DESCRIPTION
  //   Only put static methods within this scope.
  ACE_CLASS_IS_NAMESPACE (TAO_GIOP);

public:

  enum Message_Type
  {
    // = DESCRIPTION
    //   All GIOP messages include a header and message type.  Not
    //   really a message type, but needed to bring that information
    //   back somehow.

    // = GIOP message types.
    Request = 0,                // sent by client.
    Reply = 1,                  // by server.
    CancelRequest = 2,          // by client.
    LocateRequest = 3,          // by client.
    LocateReply = 4,            // by server.
    CloseConnection = 5,        // by server.
    MessageError = 6,           // by both.
    Fragment = 7                // by both.
  };

  static void send_close_connection (const TAO_GIOP_Version &version,
                                     TAO_Transport *transport,
                                     void *ctx);
  // Close a connection, first sending GIOP::CloseConnection.

  static CORBA::Boolean start_message (const TAO_GIOP_Version &version,
                                       TAO_GIOP::Message_Type t,
                                       TAO_OutputCDR &msg,
                                       TAO_ORB_Core* orb_core);
  // Build the header for a message of type <t> into stream <msg>.

  static CORBA::Boolean write_request_header (const IOP::ServiceContextList& svc_ctx,
                                              CORBA::ULong request_id,
                                              CORBA::Boolean is_roundtrip,
                                              const TAO_opaque& key,
                                              const char* opname,
                                              CORBA::Principal_ptr principal,
                                              TAO_OutputCDR &msg,
                                              TAO_ORB_Core *orb_core);
  // Write the GIOP request header.

  static CORBA::Boolean write_locate_request_header (CORBA::ULong request_id,
                                                     const TAO_opaque &key,
                                                     TAO_OutputCDR &msg);
  // Write the GIOP locate request header.

  static int send_message (TAO_Transport *transport,
                           TAO_OutputCDR &stream,
                           TAO_ORB_Core* orb_core,
                           ACE_Time_Value *max_wait_time = 0);
  // Send message, returns TRUE if success, else FALSE.

  static void dump_msg (const char *label,
                        const u_char *ptr,
                        size_t len);
  // Print out a message header.

  static int send_error (const TAO_GIOP_Version &version,
                         TAO_Transport *transport);
  // Send an error message back to a caller.

  static ssize_t read_buffer (TAO_Transport *transport,
                              char *buf,
                              size_t len,
                              ACE_Time_Value *max_wait_time);
  // Loop on data read ... this is required since <recv> won't block
  // until the requested amount of data is available.

  static TAO_GIOP_ReplyStatusType convert_CORBA_to_GIOP_exception (CORBA::exception_type corba_type);
  // Convert the exception type from CORBA to GIOP

  static int read_header (TAO_Transport *transport,
                          TAO_ORB_Core *orb_core,
                          TAO_GIOP_Message_State &state,
                          CORBA::ULong &header_size,
                          TAO_InputCDR &input,
                          ACE_Time_Value *max_wait_time);
  static int handle_input (TAO_Transport *transport,
                           TAO_ORB_Core *orb_core,
                           TAO_GIOP_Message_State &state,
                           ACE_Time_Value *max_wait_time = 0);

  static int parse_reply (TAO_Transport *transport,
                          TAO_ORB_Core *orb_core,
                          TAO_GIOP_Message_State& state,
                          IOP::ServiceContextList& reply_ctx,
                          CORBA::ULong& request_id,
                          CORBA::ULong& reply_status);

  static int process_server_message (TAO_Transport *transport,
                                     TAO_ORB_Core *orb_core,
                                     TAO_InputCDR &input,
                                     CORBA::Octet message_type,
                                     const TAO_GIOP_Version &giop_version);

  static int process_server_request (TAO_Transport *transport,
                                     TAO_ORB_Core* orb_core,
                                     TAO_InputCDR &input,
                                     TAO_OutputCDR &output,
                                     const TAO_GIOP_Version& version);
  // A request was received on the server side.
  // <transport> is the source of the message (and thus where the
  // replies should be sent).
  // <orb_core> is the ORB that received the message
  // <input> contains the message
  // <output> can be used to store any responses
  // <request_id> and <response_required> are set as part of the
  // message processing.

  static int process_server_locate (TAO_Transport *transport,
                                    TAO_ORB_Core* orb_core,
                                    TAO_InputCDR &input,
                                    TAO_OutputCDR &output,
                                    const TAO_GIOP_Version& version);
  // A LocateRequest was received on the server side.
  // <transport> is the source of the message (and thus where the
  // replies should be sent).
  // <orb_core> is the ORB that received the message
  // <input> contains the message
  // <output> can be used to store any responses
  // <request_id> and <response_required> are set as part of the
  // message processing.

  static int send_reply_exception (const TAO_GIOP_Version &version,
                                   TAO_Transport *transport,
                                   TAO_ORB_Core* orb_core,
                                   CORBA::ULong request_id,
                                   CORBA::Exception *x);
  // We must send a LocateReply through <transport>, this request
  // resulted in some kind of exception.

private:
  static CORBA::Boolean start_message_std (const TAO_GIOP_Version &version,
                                           TAO_GIOP::Message_Type t,
                                           TAO_OutputCDR &msg);
  // Build the standard header for a message of type <t> into
  // stream <msg>.

  static CORBA::Boolean start_message_lite (const TAO_GIOP_Version &version,
                                            TAO_GIOP::Message_Type t,
                                            TAO_OutputCDR &msg);
  // Build the lightweight header for a message of type <t> into
  // stream <msg>.

  static CORBA::Boolean write_request_header_std (const IOP::ServiceContextList& svc_ctx,
                                                  CORBA::ULong request_id,
                                                  CORBA::Boolean is_roundtrip,
                                                  const TAO_opaque& key,
                                                  const char* opname,
                                                  CORBA::Principal_ptr principal,
                                                  TAO_OutputCDR &msg);
  // Encode the standard header for the Request, assuming that the
  // GIOP header is already there.

  static CORBA::Boolean write_request_header_lite (const IOP::ServiceContextList& svc_ctx,
                                                   CORBA::ULong request_id,
                                                   CORBA::Boolean is_roundtrip,
                                                   const TAO_opaque& key,
                                                   const char* opname,
                                                   CORBA::Principal_ptr principal,
                                                   TAO_OutputCDR &msg);
  // Encode the light weight header for the Request, assuming that the
  // GIOP header is already there.

  static int parse_header (TAO_ORB_Core *orb_core,
                           TAO_InputCDR &input,
                           TAO_GIOP_Message_State& state);
  // Parse the header, extracting all the relevant info.

  static int parse_header_std (TAO_InputCDR &input,
                               TAO_GIOP_Message_State& state);

  static int parse_header_lite (TAO_InputCDR &input,
                                TAO_GIOP_Message_State& state);
};

#if defined (__ACE_INLINE__)
# include "tao/GIOP.i"
#endif /* __ACE_INLINE__ */

#endif /* TAO_GIOP_H */